-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxo.mank
123 lines (111 loc) · 2.67 KB
/
xo.mank
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
pod GameState {
player: i32,
board: i32[9]
}
fun get_move: i32 (state: ref GameState) {
loop {
print!("Player {player} choose your move (1-9): ",
int_to_string(state.player));
move := input_int();
if move >= 1 && move <= 9 {
move -= 1;
if state.board[move] == 0 {
return move;
}
}
println("Please enter a valid move!");
}
}
# Some terminal colour codes
const RED := 202;
const BLUE := 33 ;
const GREY := 239;
const PINK := 207;
const BRIGHT_RED := 196;
fun colour_text: str (text: str, colour_code: i32) {
"\e[38;5;" + int_to_string(colour_code) + "m" + text + "\e[0m"
}
# 1 | 2 | 3
# -----------
# 4 | 5 | 6
# -----------
# 7 | 8 | 9
proc print_board(state: ref GameState) {
for cell_idx in 0 .. 9 {
value := state.board[cell_idx];
row_pos := cell_idx % 3;
mid_cell := row_pos == 1;
if mid_cell { putchar('|'); }
print!(" {} ", {
if value == 0 {
colour_text(('0' + (cell_idx + 1) as char) as str, GREY)
} else if value == 1 {
colour_text("X", RED)
} else {
colour_text("O", BLUE)
}
});
if mid_cell { putchar('|'); }
if row_pos == 2 {
println(if cell_idx != 8 { "\n-----------"} else { "\n" });
}
}
}
fun game_over: (i32, bool) (state: ref GameState) {
win := \x,y,z,w-> {
if w != -1 { return w; }
same := x == y && y == z;
if same && x != 0 { x } else { -1 }
};
winner := -1;
zero_seen := false;
b := ref state.board;
for i in 0 .. 3 {
row := i * 3;
bind (l,m,r) = (b[row + 0],b[row + 1],b[row + 2]);
winner = win(l,m,r, winner);
# no zero & no win means draw
if l == 0 || m == 0 || r == 0 {
zero_seen = true;
}
winner = win(b[i + 0],b[i + 3],b[i + 6], winner);
}
# diags
winner = win(b[0], b[4], b[8], winner);
winner = win(b[2], b[4], b[6], winner);
if winner == -1 {
if zero_seen {
(-1, true) # still turns
} else {
(-1, false) # draw
}
} else {
(winner, false) # winner
}
}
proc main {
game := GameState {
.player = 1,
.board = [=0;9]
};
println("Welcome to Mank Noughts and Crosses!");
println(" ---------- GOTY Edition ---------- \n");
loop {
print_board(game);
move := get_move(game);
game.board[move] = game.player;
game.player = if game.player == 1 { 2 } else { 1 };
putchar('\n');
bind (winner, turns_left) = game_over(game);
if !turns_left {
print_board(game);
println(
if winner <= 0 {
colour_text("DRAW!", BRIGHT_RED)
} else {
colour_text("Winner! Player " + int_to_string(winner), PINK)
});
return;
}
}
}