Refactored directory structure

This commit is contained in:
Nocturn9x 2023-01-13 17:14:51 +01:00
parent 3f039a77e2
commit 4c88c08072
3 changed files with 41 additions and 27 deletions

View File

@ -1,3 +1,17 @@
# CPG # CPG - Computers playing games
Computers Playing Games A silly project going down the rabbithole of making the pinnacle of human advancement
in semiconductor technology smart enough to play tic tac toe.
## Plans
- Tic Tac Toe (optimal) -> Done
- Connect 4 (optinal) -> WIP
- Checkers (optimal?)
- Chess
All of these games will be played using decision trees searched using the minimax algorithm (maybe a bit of neural networks too, who knows).
Ideally I'd like to implement a bunch of stuff such as move reordering, alpha-beta pruning and transpositions in order to improve both
processing time and decision quality. Very much WIP.

View File

@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import matrix import ../util/matrix
import multibyte import../util/multibyte
export matrix export matrix

View File

@ -11,11 +11,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import util/game import board
import util/matrix import ../util/matrix
export game export board
export matrix export matrix
@ -33,54 +33,54 @@ proc play(treeA, treeB: Move) =
## Plays a game of tic tac toe ## Plays a game of tic tac toe
## against the user ## against the user
stdout.write("\x1Bc") stdout.write("\x1Bc")
var board = newTicTacToe() var game = newTicTacToe()
var moves = treeA var moves = treeA
var location: tuple[row, col: int] var location: tuple[row, col: int]
var index: int var index: int
stdout.styledWrite(fgGreen, styleBright, "Wanna start first? ", fgYellow ,"[Y/n] ") stdout.styledWrite(fgGreen, styleBright, "Wanna start first? ", fgYellow ,"[Y/n] ")
if readLine(stdin).strip(chars={'\n'}).toLowerAscii() in ["n", "no"]: if readLine(stdin).strip(chars={'\n'}).toLowerAscii() in ["n", "no"]:
moves = treeB moves = treeB
location = where(moves.state, moves.state != board.map, 3).index(Self.uint8) location = where(moves.state, moves.state != game.map, 3).index(Self.uint8)
board.place(Self, location.row, location.col) game.place(Self, location.row, location.col)
stdout.write("\x1Bc") stdout.write("\x1Bc")
styledEcho fgCyan, styleBright, "Computer chose ", fgYellow, $board.map.getIndex(location.row, location.col) styledEcho fgCyan, styleBright, "Computer chose ", fgYellow, $game.map.getIndex(location.row, location.col)
else: else:
stdout.write("\x1Bc") stdout.write("\x1Bc")
while board.get() == Playing: while game.get() == Playing:
styledEcho fgBlue, styleBright, "Tic Tac Bot v1.0" styledEcho fgBlue, styleBright, "Tic Tac Bot v1.0"
echo board, "\n" echo game, "\n"
styledEcho fgMagenta, styleBright, "You are ", fgBlue, "O" styledEcho fgMagenta, styleBright, "You are ", fgBlue, "O"
stdout.styledWrite(fgRed, styleBright, "Make your move ", fgBlue, "(", fgYellow, "0", fgGreen, "~", fgYellow, "8", fgBlue, ")", fgRed, ": ") stdout.styledWrite(fgRed, styleBright, "Make your move ", fgBlue, "(", fgYellow, "0", fgGreen, "~", fgYellow, "8", fgBlue, ")", fgRed, ": ")
flushFile(stdout) flushFile(stdout)
try: try:
index = int(parseBiggestInt(readLine(stdin).strip(chars={'\n'}))) index = int(parseBiggestInt(readLine(stdin).strip(chars={'\n'})))
location = ind2sub(index, board.map.shape) location = ind2sub(index, game.map.shape)
except ValueError: except ValueError:
stdout.write("\x1Bc") stdout.write("\x1Bc")
styledEcho fgRed, styleBright, "Invalid move" styledEcho fgRed, styleBright, "Invalid move"
continue continue
if index notin 0..8 or TileKind(board.map[location.row, location.col]) != Empty: if index notin 0..8 or TileKind(game.map[location.row, location.col]) != Empty:
stdout.write("\x1Bc") stdout.write("\x1Bc")
styledEcho fgRed, styleBright, "Invalid move" styledEcho fgRed, styleBright, "Invalid move"
continue continue
board.place(Enemy, location.row, location.col) game.place(Enemy, location.row, location.col)
stdout.write("\x1Bc") stdout.write("\x1Bc")
if board.get() == WinO: if game.get() == WinO:
echo board, "\n" echo game, "\n"
styledEcho fgGreen, styleBright, "Human wins!" styledEcho fgGreen, styleBright, "Human wins!"
return return
moves = moves.find(board.map) moves = moves.find(game.map)
moves = moves.findBest(board.map, true).move moves = moves.findBest(game.map, true).move
location = where(moves.state, moves.state != board.map, 3).index(Self.uint8) location = where(moves.state, moves.state != game.map, 3).index(Self.uint8)
board.place(Self, location.row, location.col) game.place(Self, location.row, location.col)
stdout.write("\x1Bc") stdout.write("\x1Bc")
if board.get() != Draw: if game.get() != Draw:
styledEcho fgCyan, styleBright, "Computer chose ", fgYellow, $board.map.getIndex(location.row, location.col) styledEcho fgCyan, styleBright, "Computer chose ", fgYellow, $game.map.getIndex(location.row, location.col)
if board.get() == WinX: if game.get() == WinX:
echo board, "\n" echo game, "\n"
styledEcho fgRed, styleBright, "Computer wins!" styledEcho fgRed, styleBright, "Computer wins!"
return return
echo board echo game
echo "It's a draw!" echo "It's a draw!"