Created
December 21, 2019 08:30
-
-
Save abhishalya/e4f1c659b71587fc4bba3336ed5a14f8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################# | |
# Tic-tac-toe game in Julia # | |
############################# | |
wins = [[[1, 1], [1, 2], [1, 3]], | |
[[2, 1], [2, 2], [2, 3]], | |
[[3, 1], [3, 2], [3, 3]], | |
[[1, 1], [2, 1], [3, 1]], | |
[[1, 2], [2, 2], [3, 2]], | |
[[1, 3], [2, 3], [3, 3]], | |
[[1, 1], [2, 2], [3, 3]], | |
[[1, 3], [2, 2], [3, 1]]] | |
function print_board(board) | |
println(" _ " ^ 3) | |
for i in 1 : 3 | |
println(board[i]) | |
end | |
end | |
function display_board(moves_a, moves_b) | |
display = [] | |
for i in 1 : 3 | |
display_row = "" | |
for j in 1 : 3 | |
if [i, j] in moves_a | |
display_row *= "|$player_a|" | |
elseif [i, j] in moves_b | |
display_row *= "|$player_b|" | |
else | |
display_row *= "|_|" | |
end | |
end | |
push!(display, display_row) | |
end | |
print_board(display) | |
end | |
function evaluate(moves_a, moves_b) | |
status, a_b = check_win(moves_a, moves_b) | |
if status | |
if a_b == player_b | |
return 10 | |
else | |
return -10 | |
end | |
end | |
return 0 | |
end | |
function minmax(moves_a, moves_b, depth, ismax) | |
scr = evaluate(moves_a, moves_b) | |
if scr == 10 | |
return scr | |
end | |
if scr == -10 | |
return scr | |
end | |
if length(moves_a) + length(moves_b) >= 9 | |
return 0 | |
end | |
if ismax | |
best = -1000 | |
for i in 1 : 3, j in 1 : 3 | |
if !([i, j] in moves_a) && | |
!([i, j] in moves_b) | |
push!(moves_b, [i, j]) | |
best = max(best, minmax(moves_a, moves_b, | |
depth + 1, !ismax)) | |
pop!(moves_b) | |
end | |
end | |
return best | |
else | |
best = 1000 | |
for i in 1 : 3, j in 1 : 3 | |
if !([i, j] in moves_a) && | |
!([i, j] in moves_b) | |
push!(moves_a, [i, j]) | |
best = min(best, minmax(moves_a, moves_b, | |
depth + 1, !ismax)) | |
pop!(moves_a) | |
end | |
end | |
return best | |
end | |
end | |
function move_comp(moves_a, moves_b) | |
best_val = -1000 | |
best_move = [-1, -1] | |
for i in 1 : 3, j in 1 : 3 | |
if !([i, j] in moves_a) && | |
!([i, j] in moves_b) | |
push!(moves_b, [i, j]) | |
mval = minmax(moves_a, moves_b, 0, false) | |
pop!(moves_b) | |
if mval > best_val | |
best_move = [i, j] | |
best_val = mval | |
end | |
end | |
end | |
return best_move | |
end | |
function check_win(moves_a, moves_b) | |
if any(x -> (all(y -> y in moves_a, x)), wins) | |
return true, player_a | |
end | |
if any(x -> (all(y -> y in moves_b, x)), wins) | |
return true, player_b | |
end | |
return false, player_a | |
end | |
function play() | |
println("Select Player:\n1. X\n2. O") | |
char = 1 | |
try | |
char = parse(Int64, readline(stdin)) | |
catch | |
println("Invalid choice.") | |
exit(0) | |
end | |
if char != 1 && char != 2 | |
println("Invalid choice.") | |
exit(0) | |
end | |
global char_dict = Dict(1 => 'X', 2 => 'O') | |
global player_a = char_dict[char] | |
global player_b = (player_a == 'X') ? 'O' : 'X' | |
println("Player $player_b:\n1. Human\n2. Computer") | |
opponent = 1 | |
try | |
opponent = parse(Int64, readline(stdin)) | |
catch | |
println("Invalid choice.") | |
exit(0) | |
end | |
if opponent != 1 && opponent != 2 | |
println("Invalid choice.") | |
exit(0) | |
end | |
moves_a = [] | |
moves_b = [] | |
cnt = 0 | |
while length(moves_a) + length(moves_b) < 9 | |
display_board(moves_a, moves_b) | |
player = (cnt % 2 == 0) ? 'X' : 'O' | |
if player != player_a && opponent == 2 | |
comp_move = move_comp(moves_a, moves_b) | |
push!(moves_b, comp_move) | |
println("Computer made the following move: $comp_move") | |
cnt += 1 | |
continue | |
end | |
print("Player $player Enter your move in `row col` format: ") | |
move_x, move_y = 0, 0 | |
try | |
moves = split(readline(stdin), ' ') | |
move_x = parse(Int64, moves[1]) | |
move_y = parse(Int64, moves[2]) | |
catch | |
println("Invalid syntax.") | |
end | |
if move_x < 1 || move_x > 3 || | |
move_y < 1 || move_y > 3 | |
println("Invalid move.") | |
continue | |
end | |
if player == player_a | |
if !([move_x, move_y] in moves_a) && | |
!([move_x, move_y] in moves_b) | |
push!(moves_a, [move_x, move_y]) | |
cnt += 1 | |
else | |
println("Move already made. Try again.") | |
continue | |
end | |
else | |
if !([move_x, move_y] in moves_a) && | |
!([move_x, move_y] in moves_b) | |
push!(moves_b, [move_x, move_y]) | |
cnt += 1 | |
else | |
println("Move already made. Try again.") | |
continue | |
end | |
end | |
status, a_b = check_win(moves_a, moves_b) | |
if status | |
display_board(moves_a, moves_b) | |
println("\n***Player $a_b has won!***") | |
exit(0) | |
end | |
end | |
println("\n***This is a draw.***") | |
end | |
play() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment