Do you remember Tic-tac-toe from the beginning of your programming career? The big brother is here, Five-in-a-row or Gomoku. Now, this is not a children's game, this is a serious sport with championships (actually where Eastern European countries shine) and a field of cutting edge AI research. It is a matter of national pride to create the best machine players for AI competitions and human training. Your country needs ☛you☚!
You'll have to:
- break down the game logic into parts and reassemble them into a solid game workflow
- deal with the board as 2D arrays
- write parametrized methods (flexible board size and win condition)
- move around the board programmatically in any directions
- handle edge cases (and literally the edge of the board)
- think about a simple AI algorithm
-
Implement the
Gameconstructor to initialize emptyn-by-mboard, i.e. a 2D array filled with zeros. The first coordinate is row number, the second is column number- The board is stored as a two-dimensional array (indexed by
[row, column]) - Every cell of the board is initialized with
0 - The board is accessible via the public
Boardproperty - The rows of the board are independent (changing one row doesn't affect the others)
- The board is stored as a two-dimensional array (indexed by
-
Implement
GetMove()that asks for user input and returns the coordinates of a valid move on board.- The player specifies coordinates as letter and number:
A2is first row and second column,C1is third row and first column, etc. - The function returns a tuple of integers (row, column)
- The returned coordinates start from 0
- The integers indicate a valid (empty) position on the board
- If the user provides coordinates that are outside of board, keep asking
- If the user provides coordinates for a place that is taken, keep asking
- If the user provides input that doesn't look like coordinates, keep asking
- The player specifies coordinates as letter and number:
-
Implement
Mark()that writes the value ofplayer(a1or2) into therow&colelement of the board.- If the cell at
rowandcolis empty, it is marked withplayer - It does not do anything if the coordinates are out of bounds
- It does not do anything if the cell is already marked
- If the cell at
-
Implement
HasWon()that returnstrueifplayer(of value1or2) hashowManymarks in a row on the board.- Returns
trueifplayerhashowManymarks in a row on the board. - Returns
falseifplayerdoesn't havehowManymarks in a row on the board.
- Returns
-
Implement
IsFull()that returnstrueif the board is full.- Returns
trueif there are no empty fields on the board - Returns
falseotherwise
- Returns
-
Implement
PrintBoard()that prints the board to the screen.- Players 1 and 2 are indicated with
XandO, and empty fields are indicated with dots (.) - There are coordinates displayed around the board
- A 3-by-8 board is displayed in this format:
- Players 1 and 2 are indicated with
1 2 3 4 5 6 7 8
A . . . . . . . .
B . . . . . . . .
C . . . . . . . .
-
Implement
PrintResult()that displays the result of the game.- If player 1 wins, print "X won!"
- If player 2 wins, print "O won!"
- If nobody wins, print "It's a tie!"
-
Use the implemented methods to write a
Play()method that will run a whole 2-players game. ParameterhowManysets the win condition of the game.- Player 1 starts the game
- Players alternate their moves (1, 2, 1, 2...)
- The game uses
howManyto set the win condition - The board is displayed before each move and also at the end of game
- The game ends when someone wins or the board is full
- The game handles bad input (wrong coordinates) without crashing
-
Allow players to quit the game anytime by typing
quit.- When the player types
quitinstead of coordinates, the program exits.
- When the player types
-
Implement player-against-AI mode.
- The game is fully playable against the computer, AI can play any of the players. This means that when
EnableAi()is set for a player number then it callsGetAiMove()instead ofGetMove()for that player. - Method
GetAiMove()returns a valid move (if possible) without asking for any input - Method
GetAiMove()returnsnullif board is full - Game play is easy to follow as there is a 1 second delay before each AI move implemented in method
Play()
- The game is fully playable against the computer, AI can play any of the players. This means that when
-
AI is capable of recognizing the easiest opportunities to win the game with one move.
- Method
GetAiMove()picks the winning move if there is one on the board
- Method
-
AI is capable of recognizing if its enemy could win the game with the next move, and (supposing there is no direct winning move) moves against it.
- Method
GetAiMove()(when there is no winning move in one step) picks a move which prevents a certain winning move for its enemy - When there is a direct winning move, function
GetAiMove()still picks that - When there are multiple one-step winning options for the enemy,
GetAiMove()tries to prevent one of them
- Method
-
[OPTIONAL] AI tries to look ahead more than one move. Be aware that a serious AI would follow more complicated strategies.
- If there are no direct winning or loosing options, AI should pick an option that potentionally creates a direct winning option for the next round
- As an addition to the above, if possible, AI should pick an option that potentionally creates more than one direct winning options for the next round (thus ensuring the victory)
- When none of the above options are possible, AI picks a cell that is neighbouring an already marked cell
None
- Try to come up with a general "pattern matching" feature that checks for
sequences like
X X X .or. X X .in any directions. Such ability is most likely needed for an AI. - Contrary to the introduction story, creating a really good AI for this game is way above the scope of this project. You should focus on the most basic aspects of it.
- Furthermore, you don't have to come up with an AI strategy by yourself, you can search the internet for strategy descriptions. But, for your own good, please don't use external code, implement written instructions instead.
Follow this link to create your project repository.