Skip to content

Instantly share code, notes, and snippets.

@WayneCui
Last active December 31, 2015 12:58
Show Gist options
  • Save WayneCui/7989380 to your computer and use it in GitHub Desktop.
Save WayneCui/7989380 to your computer and use it in GitHub Desktop.
井字棋游戏(Tic-tac-toe)
REBOL [
title: "A Tic Tac Toe Game to play with a clever computer."
]
tic-tac-toe: context [
keypoints: [[ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] [ 1 4 7 ] [ 2 5 8 ][ 3 6 9 ] [ 1 5 9 ][ 3 5 7 ]]
center: 5
corners: [ 1 3 7 9 ]
sides: [ 2 4 6 8 ]
validate-input: func [ input [block!] /local x y index ] [
x: input/1
y: input/2
unless all [ x y integer? x integer? y x >= 1 x <= 3 y >= 1 y <= 3 ][ return false ]
index: (x - 1) * 3 + y
?? index
board/:index = '_
]
test-over: func [ board [ block! ] /local fun f s t ][
fun: func [ 'arg ][
either letter = arg [ "You" ][ "I" ]
]
unless find board '_ [ print "tie!" return true ]
foreach point keypoints [
case [
all map-each i point [ board/:i = 'X ] [ print [ fun 'X "win!" ] return true ]
all map-each i point [ board/:i = 'O ] [ print [ fun 'O "win!" ] return true ]
]
]
]
test-over-2: func [ board [ block! ] /local fun f s t ][
unless find board '_ [ return true ]
foreach point keypoints [
case [
all map-each i point [ board/:i = 'X ] [ return true ]
all map-each i point [ board/:i = 'O ] [ return true ]
]
]
]
computer-stratege: func [ /local copy-board temp ][
temp: copy []
find-all board '_ [ append temp index? board ]
;First, check if we can win in the next move
foreach i temp [
copy-board: copy board
copy-board/:i: symbols/computer
if test-over-2 copy-board [ return i ]
]
;Second, check if the player could win on his next move, and block them.
foreach i temp [
copy-board: copy board
copy-board/:i: symbols/player
if test-over-2 copy-board [ return i ]
]
;Third, try to take one of the corners, if they are free.
case [
not empty? intersect corners temp [ first random intersect corners temp ]
find temp center [ center ]
true [ first random intersect sides temp ]
]
]
start: func [][
print "Welcome to the tic tac toe game."
print "Let's begin!"
board: array/initial 9 '_
player: random true ; 1 for player first, while 2 for computer first
until [
letter: load uppercase ask "Do you want to be X or O? "
any [ letter = 'X letter = 'O ]
]
either letter = 'X [
symbols: [ player X computer O ]
][
symbols: [ player O computer X ]
]
probe new-line/all/skip board on 3
until [
either player [
;player's move
until [
input: load parse ask "Please enter [x, y]:" none
validate-input input
]
index: (input/1 - 1) * 3 + input/2
board/:index: symbols/player
player: false
][
;computer's move
index: computer-stratege
board/:index: symbols/computer
player: true
]
probe new-line/all/skip board on 3
test-over board
]
if ( load ask "Try again? [Y/N]: ") = 'Y [ start ]
]
]
tic-tac-toe/start
REBOL [
title: "A Tic Tac Toe Game for two human being players."
]
tic-tac-toe: context [
get-input: has[ input coordinate ] [
either to-logic player [
print "It's player1's turn. (O)"
] [
print "It's player2's turn. (X)"
]
input: ask "Please input [x y]:"
coordinate: load parse input none
]
validate: func [ coordinate [ block! ] /local x y index ] [
x: coordinate/1
y: coordinate/2
unless all [ x y number? x number? y x >= 1 x <= 3 y >= 1 y <= 3 ][
print "Wrong input [1 - 3]"
return false
]
index: (x - 1) * 3 + y
unless board/:index = '_ [
print "Already in use"
return false
]
true
]
change-state: func [ coordinate [ block! ] /local index ] [
index: (coordinate/1 - 1) * 3 + coordinate/2
either to-logic player [
board/:index: 'O
probe new-line/all/skip board on 3
player: 0
][
board/:index: 'X
probe new-line/all/skip board on 3
player: 1
]
]
count-result: func [ /local rules result f s t ] [
rules: [ [ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] [ 1 4 7 ] [ 2 5 8 ] [ 3 6 9 ] [ 1 5 9 ] [ 3 5 7 ] ]
foreach rule rules [
f: first rule
s: second rule
t: third rule
case [
all [ board/:f = 'O board/:s = 'O board/:t = 'O ] [ print "Player 1 win!" return true ]
all [ board/:f = 'X board/:s = 'X board/:t = 'X ] [ print "Player 2 win!" return true ]
not find board '_ [ print "No one win!" return true ]
]
]
false
]
start: does [
print "The Tic Tac Toe Game!"
print "Player 1 for O, Player 2 for X"
print "Let's begin!"
board: array/initial 9 '_
probe new-line/all/skip board on 3
player: 1
until [
until [
coordinate: get-input
validate coordinate
]
change-state coordinate
count-result
]
input: ask "Play again? (Y/N)"
if input = "Y" [ start ]
]
]
tic-tac-toe/start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment