Marian23

tic tac toe

Feb 1st, 2020
458
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 10.12 KB | None | 0 0
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3.  
  4. class PlayerVsAi extends StatefulWidget {
  5.   @override
  6.   _PlayerVsAiState createState() => _PlayerVsAiState();
  7. }
  8.  
  9. class _PlayerVsAiState extends State<PlayerVsAi> {
  10.   @override
  11.   List<List<String>> gridState = [
  12.     [' ', ' ', ' '],
  13.     [' ', ' ', ' '],
  14.     [' ', ' ', ' '],
  15.   ];
  16.   bool isPlayer1Turn = true;
  17.   int scorePlayer = 0;
  18.   int scoreAI = 0;
  19.   List<List<bool>> _listButtonsCol = [
  20.     [false, false, false],
  21.     [false, false, false],
  22.     [false, false, false],
  23.   ];
  24.   List<List<bool>> _listButtonsEnabled = [
  25.     ///prevent errors
  26.     [true, true, true],
  27.     [true, true, true],
  28.     [true, true, true],
  29.   ];
  30.   Widget build(BuildContext context) {
  31.     SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
  32.       statusBarColor: Colors.transparent,
  33.       systemNavigationBarColor: Colors.yellow,
  34.       statusBarBrightness: Brightness.dark,
  35.       systemNavigationBarIconBrightness: Brightness.dark,
  36.     ));
  37.  
  38.     return Scaffold(
  39.       backgroundColor: Colors.grey[50],
  40.       appBar: AppBar(
  41.         title: Text(
  42.           'Player vs AI',
  43.           style: TextStyle(color: Colors.black),
  44.         ),
  45.         centerTitle: true,
  46.         backgroundColor: Colors.yellow[600],
  47.       ),
  48.       body: Container(
  49.         width: MediaQuery.of(context).size.width,
  50.         height: MediaQuery.of(context).size.height,
  51.         decoration: BoxDecoration(
  52.           image: DecorationImage(
  53.             image: AssetImage("assets/images/img_bg.jpg"),
  54.             fit: BoxFit.cover,
  55.           ),
  56.         ),
  57.         child: Container(
  58.           margin: EdgeInsets.fromLTRB(10, 20, 10, 120),
  59.           child: Table(
  60.             children: [
  61.               TableRow(children: [
  62.                 Container(
  63.                   margin: const EdgeInsets.fromLTRB(0, 120, 5, 0),
  64.                   child: _buildCeil(gridState[0][0], 0, 0),
  65.                 ),
  66.                 Container(
  67.                   margin: const EdgeInsets.fromLTRB(5, 120, 0, 0),
  68.                   child: _buildCeil(gridState[0][1], 0, 1),
  69.                 ),
  70.                 Container(
  71.                   margin: const EdgeInsets.fromLTRB(10, 120, 0, 0),
  72.                   child: _buildCeil(gridState[0][2], 0, 2),
  73.                 ),
  74.               ]),
  75.               TableRow(children: [
  76.                 Container(
  77.                   margin: const EdgeInsets.fromLTRB(0, 10, 5, 0),
  78.                   child: _buildCeil(gridState[1][0], 1, 0),
  79.                 ),
  80.                 Container(
  81.                   margin: const EdgeInsets.fromLTRB(5, 10, 0, 0),
  82.                   child: _buildCeil(gridState[1][1], 1, 1),
  83.                 ),
  84.                 Container(
  85.                   margin: const EdgeInsets.fromLTRB(10, 10, 0, 0),
  86.                   child: _buildCeil(gridState[1][2], 1, 2),
  87.                 ),
  88.               ]),
  89.               TableRow(children: [
  90.                 Container(
  91.                   margin: const EdgeInsets.fromLTRB(0, 10, 5, 0),
  92.                   child: _buildCeil(gridState[2][0], 2, 0),
  93.                 ),
  94.                 Container(
  95.                   margin: const EdgeInsets.fromLTRB(5, 10, 0, 0),
  96.                   child: _buildCeil(gridState[2][1], 2, 1),
  97.                 ),
  98.                 Container(
  99.                   margin: const EdgeInsets.fromLTRB(10, 10, 0, 0),
  100.                   child: _buildCeil(gridState[2][2], 2, 2),
  101.                 ),
  102.               ]),
  103.             ],
  104.           ),
  105.         ),
  106.       ),
  107.     );
  108.   }
  109.  
  110.   FlatButton _buildCeil(String val, int x, int y) {
  111.     return FlatButton(
  112.       shape: RoundedRectangleBorder(
  113.         borderRadius: new BorderRadius.circular(18.0),
  114.       ),
  115.       color: _listButtonsCol[x][y] ? Colors.red[400] : Colors.yellow[500],
  116.       textColor: _listButtonsCol[x][y] ? Colors.yellow[500] : Colors.black,
  117.       disabledColor: Colors.grey,
  118.       disabledTextColor: Colors.black,
  119.       padding: EdgeInsets.fromLTRB(8, 18, 8, 18),
  120.       splashColor: Colors.yellow[600],
  121.       onPressed: () {
  122.         if (_listButtonsEnabled[x][y]) gameLogic(val, x, y);
  123.       },
  124.       child: Text(
  125.         val,
  126.         style: TextStyle(fontSize: 50.0),
  127.       ),
  128.     );
  129.   }
  130. //----------------------------------------------------------< - AI & Game Logic - >---------------------------------------------------
  131.  
  132.   void gameLogic(String val, int x, int y) {
  133.     testIfMustStartNewGame(val, x, y);
  134.     if (val == ' ') {
  135.       if (isPlayer1Turn) {
  136.         _listButtonsEnabled = [
  137.           [false, false, false],
  138.           [false, false, false],
  139.           [false, false, false],
  140.         ];
  141.         val = 'X';
  142.         gridState[x][y] = 'X';
  143.         setState(() {});
  144.         testIfMustStartNewGame(val, x, y);
  145.         Future.delayed(const Duration(milliseconds: 500), () {
  146.           setState(() {
  147.             if (isMovesLeft(gridState)) {
  148.               List bestMove = findBestMove(gridState);
  149.               gridState[bestMove[0]][bestMove[1]] = 'O';
  150.               drawLine(gridState);
  151.               testIfMustStartNewGame(val, x, y);
  152.               _listButtonsEnabled = [
  153.                 [true, true, true],
  154.                 [true, true, true],
  155.                 [true, true, true],
  156.               ];
  157.             }
  158.           });
  159.         });
  160.         drawLine(gridState);
  161.         testIfMustStartNewGame(val, x, y);
  162.       }
  163.     }
  164.   }
  165.  
  166.   void testIfMustStartNewGame(String val, int x, int y) {
  167.     if (evaluate(gridState) == 10) {
  168.       Future.delayed(const Duration(milliseconds: 500), () {
  169.         setState(() {
  170.           for (int i = 0; i < 3; ++i) {
  171.             for (int j = 0; j < 3; ++j) {
  172.               gridState[i][j] = ' ';
  173.               _listButtonsCol[i][j] = false;
  174.             }
  175.           }
  176.         });
  177.       });
  178.     }
  179.     if (evaluate(gridState) == -10) {
  180.       Future.delayed(const Duration(milliseconds: 500), () {
  181.         setState(() {
  182.           for (int i = 0; i < 3; ++i) {
  183.             for (int j = 0; j < 3; ++j) {
  184.               gridState[i][j] = ' ';
  185.               _listButtonsCol[i][j] = false;
  186.             }
  187.           }
  188.         });
  189.       });
  190.     }
  191.     if (!isMovesLeft(gridState)) {
  192.       Future.delayed(const Duration(milliseconds: 500), () {
  193.         setState(() {
  194.           for (int i = 0; i < 3; ++i) {
  195.             for (int j = 0; j < 3; ++j) {
  196.               gridState[i][j] = ' ';
  197.             }
  198.           }
  199.         });
  200.       });
  201.     }
  202.   }
  203.  
  204.   void drawLine(List<List<String>> b) {
  205.     Future.delayed(const Duration(milliseconds: 500), () {
  206.       setState(() {
  207.         for (int row = 0; row < 3; row++) {
  208.           if (b[row][0] == b[row][1] && b[row][1] == b[row][2]) {
  209.             if (b[row][0] == 'O')
  210.               _listButtonsCol[row][0] =
  211.                   _listButtonsCol[row][1] = _listButtonsCol[row][2] = true;
  212.           }
  213.         }
  214.         for (int col = 0; col < 3; col++) {
  215.           if (b[0][col] == b[1][col] && b[1][col] == b[2][col]) {
  216.             if (b[0][col] == 'O')
  217.               _listButtonsCol[0][col] =
  218.                   _listButtonsCol[1][col] = _listButtonsCol[2][col] = true;
  219.           }
  220.         }
  221.         if (b[0][0] == b[1][1] && b[1][1] == b[2][2]) {
  222.           if (b[0][0] == 'O')
  223.             _listButtonsCol[0][0] =
  224.                 _listButtonsCol[1][1] = _listButtonsCol[2][2] = true;
  225.         }
  226.  
  227.         if (b[0][2] == b[1][1] && b[1][1] == b[2][0]) {
  228.           if (b[0][2] == 'O')
  229.             _listButtonsCol[0][2] =
  230.                 _listButtonsCol[1][1] = _listButtonsCol[2][0] = true;
  231.         }
  232.       });
  233.     });
  234.   }
  235.  
  236.   bool isMovesLeft(List<List<String>> board) {
  237.     for (int i = 0; i < 3; i++)
  238.       for (int j = 0; j < 3; j++) if (board[i][j] == ' ') return true;
  239.     return false;
  240.   }
  241.  
  242.   int evaluate(List<List<String>> b) {
  243.     for (int row = 0; row < 3; row++) {
  244.       if (b[row][0] == b[row][1] && b[row][1] == b[row][2]) {
  245.         if (b[row][0] == 'O')
  246.           return 10;
  247.         else if (b[row][0] == 'X') return -10;
  248.       }
  249.     }
  250.     for (int col = 0; col < 3; col++) {
  251.       if (b[0][col] == b[1][col] && b[1][col] == b[2][col]) {
  252.         if (b[0][col] == 'O')
  253.           return 10;
  254.         else if (b[0][col] == 'X') return -10;
  255.       }
  256.     }
  257.     if (b[0][0] == b[1][1] && b[1][1] == b[2][2]) {
  258.       if (b[0][0] == 'O')
  259.         return 10;
  260.       else if (b[0][0] == 'X') return -10;
  261.     }
  262.  
  263.     if (b[0][2] == b[1][1] && b[1][1] == b[2][0]) {
  264.       if (b[0][2] == 'O')
  265.         return 10;
  266.       else if (b[0][2] == 'X') return -10;
  267.     }
  268.     return 0;
  269.   }
  270.  
  271.   int minimax(List<List<String>> board, int depth, bool isMax) {
  272.     int score = evaluate(board);
  273.     if (score == 10) return score;
  274.     if (score == -10) return score;
  275.     if (isMovesLeft(board) == false) return 0;
  276.     if (isMax) {
  277.       int best = -1000;
  278.       for (int i = 0; i < 3; i++) {
  279.         for (int j = 0; j < 3; j++) {
  280.           if (board[i][j] == ' ') {
  281.             board[i][j] = 'O';
  282.             int resultMiniMax = minimax(board, depth + 1, !isMax);
  283.             if (resultMiniMax > best) {
  284.               best = resultMiniMax;
  285.             }
  286.             board[i][j] = ' ';
  287.           }
  288.         }
  289.       }
  290.       return best;
  291.     } else {
  292.       int best = 1000;
  293.       for (int i = 0; i < 3; i++) {
  294.         for (int j = 0; j < 3; j++) {
  295.           if (board[i][j] == ' ') {
  296.             board[i][j] = 'X';
  297.             int resultMiniMax = minimax(board, depth + 1, !isMax);
  298.             if (best > resultMiniMax) {
  299.               best = resultMiniMax;
  300.             }
  301.             board[i][j] = ' ';
  302.           }
  303.         }
  304.       }
  305.       return best;
  306.     }
  307.   }
  308.  
  309.   List findBestMove(List<List<String>> board) {
  310.     int bestVal = -1000;
  311.     // List bestMove;
  312.     List<int> bestMove = new List(2);
  313.     bestMove[0] = -1;
  314.     bestMove[1] = -1;
  315.  
  316.     for (int i = 0; i < 3; i++) {
  317.       for (int j = 0; j < 3; j++) {
  318.         if (board[i][j] == ' ') {
  319.           board[i][j] = 'O';
  320.           int moveVal = minimax(board, 0, false);
  321.           board[i][j] = ' ';
  322.           if (moveVal > bestVal) {
  323.             bestMove[0] = i;
  324.             bestMove[1] = j;
  325.             bestVal = moveVal;
  326.           }
  327.         }
  328.       }
  329.     }
  330.     return bestMove;
  331.   }
  332. }
Add Comment
Please, Sign In to add comment