Skip to content
Snippets Groups Projects
Select Git revision
  • 051c212a48f3d4f0b4300f1534db12658c27c76f
  • master default protected
  • 94-upgrade-framework-and-dependencies
  • 77-improve-app-metadata
  • 68-add-words
  • 62-fix-get-image-when-word-with-accent
  • 44-implement-game-write-word-from-letters
  • 43-add-script-to-get-images-from-assets
  • 32-add-accents-and-diacritics-in-french-words-2
  • Release_0.10.0_80 protected
  • Release_0.9.2_79 protected
  • Release_0.9.1_78 protected
  • Release_0.9.0_77 protected
  • Release_0.8.0_76 protected
  • Release_0.7.0_75 protected
  • Release_0.6.0_74 protected
  • Release_0.5.2_73 protected
  • Release_0.5.1_72 protected
  • Release_0.5.0_71 protected
  • Release_0.4.1_70 protected
  • Release_0.4.0_69 protected
  • Release_0.3.1_68 protected
  • Release_0.3.0_67 protected
  • Release_0.2.1_66 protected
  • Release_0.2.0_65 protected
  • Release_0.1.40_64 protected
  • Release_0.1.39_63 protected
  • Release_0.1.38_62 protected
  • Release_0.1.37_61 protected
29 results

data.dart

Blame
  • match_page.dart 7.53 KiB
    import 'dart:math';
    
    import 'package:flutter/material.dart';
    import 'package:puissance4/coordinate.dart';
    
    import 'board.dart';
    import 'cpu.dart';
    import 'game_chip.dart';
    import 'hole_painter.dart';
    
    enum Color {
      YELLOW,
      RED,
    }
    
    enum Mode {
      PVP,
      PVC,
      DEMO,
    }
    
    class MatchPage extends StatefulWidget {
      final Mode mode;
      final Cpu cpu;
      final Cpu cpu2;
    
      const MatchPage({
        Key key,
        this.mode,
        this.cpu,
        this.cpu2,
      }) : super(key: key);
    
      @override
      _MatchPageState createState() => _MatchPageState();
    }
    
    class _MatchPageState extends State<MatchPage> with TickerProviderStateMixin {
      final board = Board();
      Color turn;
      Color winner;
    
      List<List<Animation<double>>> translations = List.generate(
        7,
        (i) => List.generate(
          7,
          (i) => null,
        ),
      );
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            elevation: 0,
          ),
          backgroundColor: Colors.blue,
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Flex(
              direction: Axis.vertical,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                Flexible(
                  flex: 2,
                  child: Container(
                    constraints: BoxConstraints.loose(
                      Size(
                        500,
                        532,
                      ),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.only(top: 32.0),
                      child: Stack(
                        overflow: Overflow.clip,
                        fit: StackFit.loose,
                        children: <Widget>[
                          Positioned.fill(
                            child: Container(
                              color: Colors.white,
                            ),
                          ),
                          buildPieces(),
                          buildBoard(),
                        ],
                      ),
                    ),
                  ),
                ),
                Flexible(
                  flex: 1,
                  child: Padding(
                    padding: const EdgeInsets.all(32.0),
                    child: winner != null
                        ? Text(
                            '${winner == Color.RED ? 'RED' : 'YELLOW'} WINS',
                            textAlign: TextAlign.center,
                            style: Theme.of(context)
                                .textTheme
                                .headline6
                                .copyWith(color: Colors.white),
                          )
                        : Column(
                            children: <Widget>[
                              Text(
                                '${turn == Color.RED ? 'RED' : 'YELLOW'} SPEAKS',
                                textAlign: TextAlign.center,
                                style: Theme.of(context)
                                    .textTheme
                                    .headline5
                                    .copyWith(color: Colors.white),
                              ),
                              Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: GameChip(color: turn),
                              ),
                              _buildPlayerName(context),
                            ],
                          ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    
      Text _buildPlayerName(BuildContext context) {
        String name;
    
        if (widget.mode == Mode.PVC) {
          if (turn == widget.cpu.color) {
            name = 'CPU - ${widget.cpu.toString()}';
          } else {
            name = 'USER';
          }
        } else if (widget.mode == Mode.PVP) {
          if (turn == Color.RED) {
            name = 'PLAYER1';
          } else {
            name = 'PLAYER2';
          }
        } else {
          if (turn == widget.cpu.color) {
            name = 'CPU1 - ${widget.cpu.toString()}';
          } else {
            name = 'CPU2 - ${widget.cpu2.toString()}';
          }
        }
        return Text(
          name,
          textAlign: TextAlign.center,
          style: Theme.of(context)
            .textTheme
            .headline5
            .copyWith(color: Colors.white),
        );
      }
    
      @override
      void initState() {
        super.initState();
        turn = widget.cpu?.otherPlayer ??
            (Random().nextBool() ? Color.RED : Color.YELLOW);
        if (widget.mode == Mode.PVC && turn == widget.cpu.color) {
          cpuMove(widget.cpu);
        } else if (widget.mode == Mode.DEMO) {
          if (turn == widget.cpu.color) {
            cpuMove(widget.cpu);
          } else {
            cpuMove(widget.cpu2);
          }
        }
      }
    
      GridView buildPieces() {
        return GridView.custom(
          padding: const EdgeInsets.all(0),
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          gridDelegate:
              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 7),
          childrenDelegate: SliverChildBuilderDelegate(
            (context, i) {
              final col = i % 7;
              final row = i ~/ 7;
    
              if (board.getBox(Coordinate(col, row)) == null) {
                return SizedBox();
              }
    
              return GameChip(
                translation: translations[col][row],
                color: board.getBox(Coordinate(col, row)),
              );
            },
            childCount: 49,
          ),
        );
      }
    
      GridView buildBoard() {
        return GridView.custom(
          padding: const EdgeInsets.all(0),
          physics: NeverScrollableScrollPhysics(),
          gridDelegate:
              SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 7),
          shrinkWrap: true,
          childrenDelegate: SliverChildBuilderDelegate(
            (context, i) {
              final col = i % 7;
    
              return GestureDetector(
                onTap: () {
                  if (winner == null) {
                    userMove(col);
                  }
                },
                child: CustomPaint(
                  size: Size(50, 50),
                  willChange: false,
                  painter: HolePainter(),
                ),
              );
            },
            childCount: 49,
          ),
        );
      }
    
      void userMove(int col) {
        putChip(col);
        if (winner == null && widget.mode == Mode.PVC) {
          cpuMove(widget.cpu);
        }
      }
    
      void cpuMove(Cpu cpu) async {
        int col = await cpu.chooseCol(board);
        putChip(col);
    
        if (winner == null && widget.mode == Mode.DEMO) {
          if (turn == widget.cpu.color) {
            cpuMove(widget.cpu);
          } else {
            cpuMove(widget.cpu2);
          }
        }
      }
    
      void putChip(int col) {
        final target = board.getColumnTarget(col);
        final player = turn;
    
        if (target == -1) {
          return;
        }
    
        final controller = AnimationController(
          vsync: this,
          duration: Duration(seconds: 1),
        )..addListener(() {
            if (mounted) {
              setState(() {});
            }
          });
    
        if (mounted) {
          setState(() {
            board.setBox(Coordinate(col, target), turn);
            turn = turn == Color.RED ? Color.YELLOW : Color.RED;
          });
        }
    
        translations[col][target] = Tween(
          begin: 0.0,
          end: 1.0,
        ).animate(CurvedAnimation(
          curve: Curves.bounceOut,
          parent: controller,
        ))
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.dispose();
            }
          });
    
        controller.forward().orCancel;
    
        if (board.checkWinner(Coordinate(col, target), player)) {
          showWinnerDialog(context, player);
        }
      }
    
      void showWinnerDialog(BuildContext context, Color player) {
        setState(() {
          winner = player;
        });
    
        Future.delayed(
          Duration(seconds: 5),
          () => mounted ? Navigator.popUntil(context, (r) => r.isFirst) : null,
        );
      }
    
      void resetBoard() {
        setState(() {
          winner = null;
          board.reset();
        });
      }
    }