🍃

ChatGPT で Flutter 3 の tictactoe ゲーム

2023/03/13に公開

ChatGPT で Flutter 3 の tictactoe ゲーム

chatGPT にプログラミングさせてみた。
そのままでは動作しなかったが、少しの修正をするだけで、動作した。恐るべし!

プログラム実行の様子の動画; https://www.youtube.com/watch?v=g87gc98fthU

質問文:

you are programmer using flutter 3. please show complete code for tictactoe using flutter 3.

最初の回答:

import 'package:flutter/material.dart';

void main() => runApp(TicTacToe());

class TicTacToe extends StatelessWidget {
  const TicTacToe({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Tic Tac Toe',
      home: const TicTacToeGame(),
    );
  }
}

class TicTacToeGame extends StatefulWidget {
  const TicTacToeGame({Key? key}) : super(key: key);

  @override
  _TicTacToeGameState createState() => _TicTacToeGameState();
}

class _TicTacToeGameState extends State<TicTacToeGame> {
  List<List<String>> _board;
  bool _player1Turn = true;
  String? _winner;

  @override
  void initState() {
    super.initState();
    _board = List.generate(3, (_) => List.generate(3, (_) => ''));
  }

  void _playMove(int row, int col) {
    if (_board[row][col] == '' && _winner == null) {
      setState(() {
        _board[row][col] = _player1Turn ? 'X' : 'O';
        _player1Turn = !_player1Turn;
        _winner = _checkForWinner();
      });
    }
  }

  String? _checkForWinner() {
    // Check rows
    for (int i = 0; i < 3; i++) {
      if (_board[i][0] == _board[i][1] &&
          _board[i][1] == _board[i][2] &&
          _board[i][0] != '') {
        return _board[i][0];
      }
    }

    // Check columns
    for (int i = 0; i < 3; i++) {
      if (_board[0][i] == _board[1][i] &&
          _board[1][i] == _board[2][i] &&
          _board[0][i] != '') {
        return _board[0][i];
      }
    }

    // Check diagonals
    if (_board[0][0] == _board[1][1] &&
        _board[1][1] == _board[2][2] &&
        _board[0][0] != '') {
      return _board[0][0];
    }
    if (_board[0][2] == _board[1][1] &&
        _board[1][1] == _board[2][0] &&
        _board[0][2] != '') {
      return _board[0][2];
    }

    // Check for tie
    if (_board.every((row) => row.every((cell) => cell != ''))) {
      return 'Tie';
    }

    // No winner yet
    return null;
  }

  void _resetGame() {
    setState(() {
      _board = List.generate(3, (_) => List.generate(3, (_) => ''));
      _player1Turn = true;
      _winner = null;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Tic Tac Toe'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            for (int row = 0; row < 3; row++)
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  for (int col =

ここで 回答が切れたので、
"please continue" 
として、続きを要求した。

0; col < 3; col++)
GestureDetector(
onTap: () => _playMove(row, col),
child: Container(
width: 80,
height: 80,
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
),
alignment: Alignment.center,
child: Text(
_board[row][col],
style: TextStyle(fontSize: 40),
),
),
),
],
),
if (_winner != null)
Column(
children: [
SizedBox(height: 20),
Text(
_winner == 'Tie'
? 'It's a tie!'
: 'Player ${_winner == 'X' ? '1' : '2'} wins!',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _resetGame,
child: Text('Play Again'),
),
],
),
],
),
),
);
}
}

This code is similar to the previous code, with a few differences. First, we no longer need to import `material.dart` explicitly because it is included in the Flutter SDK by default in Flutter 3. Second, we no longer need to add the `late` keyword to the `_board`, `_player1Turn`, and `_winner` variables because null safety is now enabled by default in Flutter 3. Finally, we use a `Container` instead of a `Stack` to show the X's and O's in the cells because it is more efficient.

I hope this helps! Let me know if you have any questions.

Regenerate response

上のコードを lib/maim.dart に paste して、 indent を整えた。
3 つほどのエラーを解消させて、 chrome で動作させたら、それなりに動作した。

vscode 上で示されたエラーを解消させただけのコード:

import 'package:flutter/material.dart';

void main() => runApp(const TicTacToe());

class TicTacToe extends StatelessWidget {
 const TicTacToe({Key? key}) : super(key: key);

 @override
 Widget build(BuildContext context) {
   return const MaterialApp(
     title: 'Tic Tac Toe',
     home: TicTacToeGame(),
   );
 }
}

class TicTacToeGame extends StatefulWidget {
 const TicTacToeGame({Key? key}) : super(key: key);

 @override
 TicTacToeGameState createState() => TicTacToeGameState();
}

class TicTacToeGameState extends State<TicTacToeGame> {
 List<List<String>> _board = List.generate(3, (_) => List.generate(3, (_) => ''));
 bool _player1Turn = true;
 String? _winner;

 @override
 void initState() {
   super.initState();
   // _board = List.generate(3, (_) => List.generate(3, (_) => ''));
 }

 void _playMove(int row, int col) {
   if (_board[row][col] == '' && _winner == null) {
     setState(() {
       _board[row][col] = _player1Turn ? 'X' : 'O';
       _player1Turn = !_player1Turn;
       _winner = _checkForWinner();
     });
   }
 }

 String? _checkForWinner() {
   // Check rows
   for (int i = 0; i < 3; i++) {
     if (_board[i][0] == _board[i][1] &&
         _board[i][1] == _board[i][2] &&
         _board[i][0] != '') {
       return _board[i][0];
     }
   }

   // Check columns
   for (int i = 0; i < 3; i++) {
     if (_board[0][i] == _board[1][i] &&
         _board[1][i] == _board[2][i] &&
         _board[0][i] != '') {
       return _board[0][i];
     }
   }

   // Check diagonals
   if (_board[0][0] == _board[1][1] &&
       _board[1][1] == _board[2][2] &&
       _board[0][0] != '') {
     return _board[0][0];
   }
   if (_board[0][2] == _board[1][1] &&
       _board[1][1] == _board[2][0] &&
       _board[0][2] != '') {
     return _board[0][2];
   }

   // Check for tie
   if (_board.every((row) => row.every((cell) => cell != ''))) {
     return 'Tie';
   }

   // No winner yet
   return null;
 }

 void _resetGame() {
   setState(() {
     _board = List.generate(3, (_) => List.generate(3, (_) => ''));
     _player1Turn = true;
     _winner = null;
   });
 }

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: const Text('Tic Tac Toe'),
     ),
     body: Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: [
           for (int row = 0; row < 3; row++)
             Row(
               mainAxisAlignment: MainAxisAlignment.center,
               children: [
                 for (int col = 0; col < 3; col++)
                   GestureDetector(
                     onTap: () => _playMove(row, col),
                     child: Container(
                       width: 80,
                       height: 80,
                       decoration: BoxDecoration(
                         border: Border.all(color: Colors.black),
                       ),
                       alignment: Alignment.center,
                       child: Text(
                         _board[row][col],
                         style: TextStyle(fontSize: 40),
                         ),
                       ),
                   ),
               ],
             ),
           if (_winner != null)
             Column(
               children: [
                 SizedBox(height: 20),
                 Text(
                   _winner == 'Tie' ? 'It is a tie!' : 'Player ${_winner == 'X' ? '1' : '2'} wins!',
                   style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                 ),
                 const SizedBox(height: 20),
                 ElevatedButton(
                   onPressed: _resetGame,
                   child: Text('Play Again'),
                 ),
               ],
             ),
           ],
           ),
       ),
     );
   }
 }

動作画面例:

Discussion