Awk’s original intended use is as a stream processor, and in fact in its most basic form you can’t even do explicit input. My first version of this used gawk/nawk extensions for that purpose, but I figured it would be a bit more fun to use input patterns, so that’s what you see here.
Perl fans (and thus, Ruby and Python fans) might recognize an ancestor here.
#!/usr/bin/env awk -f
BEGIN {
split("1 2 3 4 5 6 7 8 9", spaces)
player = "X"
print_board()
print_prompt()
}
/[0-9]/ { place_move($1) }
/./ { print_board(); print_prompt() }
function print_board () {
print ""
for (i = 1; i <= 9; i++) {
space = spaces[i]
if (space ~ /[0-9]/)
printf("(%d)", space);
else
printf(" %s ", space);
if (i % 3 == 0) {
if (i / 3 < 3) {
printf "\n---+---+---\n";
}
} else {
printf "|";
}
}
print "\n"
}
function print_prompt () {
printf "Select a square, %s: ", player
}
function read_move () {
getline move
}
function place_move (move) {
if (move && spaces[move] == move) {
spaces[move] = player
good_move = 0
if (keep_playing()) {
swap_player()
} else {
exit 0
}
}
}
function swap_player () {
if (player == "X")
player = "O"
else
player = "X"
}
function m3(i, j, k) {
return spaces[i] == spaces[j] && spaces[j] == spaces[k]
}
function has_winner () {
return m3(1,2,3) ||
m3(4,5,6) ||
m3(7,8,9) ||
m3(1,4,7) ||
m3(2,5,8) ||
m3(3,6,9) ||
m3(1,5,9) ||
m3(3,5,7);
}
function is_draw () {
for (i = 1; i <= 9; i++) {
space = spaces[i]
if (space ~ /[0-9]/)
return 0;
}
return 1
}
function keep_playing() {
if (has_winner()) {
print_board()
printf("%s Wins!\n", player)
return 0;
} else if (is_draw()) {
print_board()
print("It's a Draw!")
return 0;
} else
return 1;
}
Advertisement
0 Responses to “Tic-Tac-Toe: Awk”