Creating A Simple Tic-tac-toe Game With Dart Programming Language

Tic-tac-toe, a classic game that uses noughts and crosses, or Xs and Os, involves two players who take turns marking the spaces in a three-by-three grid with X or O. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row is the winner.

Features of The Game

  • The game is played on a grid that's 3 squares by 3 squares.

  • You are X, and your friend (or the computer) is O. Players take turns putting their marks in empty squares.

  • The first player to get 3 of their marks in a row (up, down, across, or diagonally) is the winner.

  • When all 9 squares are full, the game is over and it is a draw.

Steps in Achieving this Task

  1. Firstly, import the following packages on dart, dart:io and dart:core. The dart:core library provides basic collections, such as List, Map, and Set while dart:io library allows one to work with files, directories, sockets, processes, HTTP servers and clients, and more.

  2. Create a boolean and set it to false because at the start of the game, it is assumed that no player has won. Then, create another boolean and defined it as isXturn and set it as true. This boolean initiates whose turn it is to play.

  3. Create a list of numbers from 1 to 9 and make possible combinations called co-ordinates, that if any of these co-ordinates are played, it would decide that a player has won.

  4. The board can be created using dash(_ _) and lines (| |), values from the arrays are then passed into each box.

  5. Create two variables called generateBoard and getnextCharacter. The first variable is used to create a function that builds the board in num 4 above, void generateBoard(). The second variable is used to get the user input of either X or O where we introduce the ternary operator ?, the shorthand for an if/else statement. This statement would ensure that when it is X turn, X will display and vice versa for O.

  6. Initiate an integer variable called int.parse(stdin.readLineSync) from the dart:io library to convert the number inputted by the player as a string as X or O.

  7. Use isXturn = !isXturn; to change player's turn and use cordinates[number - 1] = isXturn ? 'X' : 'O'; to change each player's co-ordinates. Normally, for a player to win, he or she must play 3 or at most 6 turns but in a case where if (movementCount == 9), it would be a draw. Optionally, you can initiate the clearScreen(); to clear the screen if a draw occurs.

  8. Initiate another variable called checkWinner where the For loop is used to ascertain the winner at every move of each player and if winner==false (means no winner), it breaks. However, there is a recursive function, a function that calls itself if (winner == false) getnextCharacter();

  9. The game can be run on Mac OS or Windows depending on the type of Process used. Process is a thread that runs the application. Create an if else statement that tells the console to run the app if it is windows or Mac OS.

Code Example

COPY

import 'dart:io';
import 'dart:core';

bool winner = false;
bool isXturn = true;

List<String> cordinates = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
List<String> combinations = ['012', '048', '036', '147', '246', '258', '345', '678'];
void main() {
  generateBoard();
  getnextCharacter();
}
int movementCount = 0;
//check if a combination is true or false for a player (X or 0)
bool checkCombination(String combination, String checkFor) {
  //split the numbers in a list of integers
  List<int> numbers = combination.split('').map((item) {
    return int.parse(item);
  }).toList();
  bool match = false;
  for (final item in numbers) {
    if (cordinates[item] == checkFor) {
      match = true;
    } else {
      match = false;
      break;
    }
  }
  return match;
}
void checkWinner(player) {
  for (final item in combinations) {
    bool combinationValidity = checkCombination(item, player);
    if (combinationValidity == true) {
      print('$player WON!');
      winner = true;
      break;
    }
  }
}
//get input, check winners
void getnextCharacter() {
  //get input from player
  print('Choose Number for ${isXturn == true ? "X" : "O"}');
  int number = int.parse(stdin.readLineSync()!);
  //change the value of selected number in cordinates
  cordinates[number - 1] = isXturn ? 'X' : 'O';
  //change player turn
  isXturn = !isXturn;
  //increment move count
  movementCount++;
  if (movementCount == 9) {
    winner = true;
    print('DRAW!');
  } else {

    //clear the console
    clearScreen();

    //redraw the board with the new information
    generateBoard();
  }
  //
  //Check Validity for players, declare winner
  //
  //check validity for player X
  checkWinner('X');
  //check validity for player O
  checkWinner('O');

  //until we have a winner, we call current function again
  if (winner == false) getnextCharacter();
}
//clear console screen
void clearScreen() {
  if (Platform.isWindows) {
    print(Process.runSync("cls", [], runInShell: true).stdout);
  } else {
    print(Process.runSync("clear", [], runInShell: true).stdout);
  }
}
//show current state of board
void generateBoard() {
  print('   |   |   ');
  print(' ${cordinates[0]} | ${cordinates[1]} | ${cordinates[2]} ');
  print('___|___|___');
  print('   |   |   ');
  print(' ${cordinates[3]} | ${cordinates[4]} | ${cordinates[5]} ');
  print('___|___|___');
  print('   |   |   ');
  print(' ${cordinates[6]} | ${cordinates[7]} | ${cordinates[8]} ');
  print('   |   |   ');

}

Summary

This article has outlined the basics of creating a functional tic-tac-toe game using the dart programming language in a very understandable manner. The code example includes a tictactoe game that can be played between two players effectively. Have fun!