CS1950Y Lecture #6-8: Tic Tac Toe Board Code
Date 2/4-2/8, 2019
// Feb 4th + Feb 6th
abstract sig Player {}
one sig X extends Player {}
one sig O extends Player {}
abstract sig Index {}
one sig One extends Index {}
one sig Two extends Index {}
one sig Three extends Index {}
sig Board {
places: (Index -> Index) -> Player
}
fact atMostOnePerSquare {
all b: Board | {
all r, c: Index | {
//#b.places[r][c] <= 1
lone b.places[r][c]
}
}
}
run notenough {#places = 9} for 3 int
// give 2^5 ints to count with (32)
run enough {#places = 9} for 5 int
pred xturn[b: Board] {
#{r, c: Index | b.places[r][c] = X} =
#{r, c: Index | b.places[r][c] = O}
}
pred oturn[b: Board] {
// not xturn[b]
sub[#{r, c: Index | b.places[r][c] = X}, 1] =
#{r, c: Index | b.places[r][c] = O}
}
run xturn for 5 int
run oturn for 5 int
pred winning[b: Board, p: Player] {
winH[b, p] or
winV[b, p] or
winD[b, p]
}
pred winH[b: Board, p: Player] {
// b.places[One][One] = p and b.places[One][Two] = p and b.places[One][Three] = p
some r: Index | {
b.places[r][One] = p
b.places[r][Two] = p
b.places[r][Three] = p
}
}
pred winV[b: Board, p: Player] {
some c: Index | {
b.places[One][c] = p
b.places[Two][c] = p
b.places[Three][c] = p
}
}
pred winD[b: Board, p: Player] {
(b.places[One][One] = p and
b.places[Two][Two] = p and
b.places[Three][Three] = p)
or
(b.places[One][Three] = p and
b.places[Two][Two] = p and
b.places[Three][One] = p)
}
pred valid[b: Board] {
xturn[b] || oturn[b]
}
run winningvalid {
some b: Board |
some p: Player |
winning[b, p] and valid[b]
} for 5 int
pred move[b: Board, r,c: Index, p: Player, b': Board] {
no b.places[r][c]
//b'.places[r][c] = p
b'.places = b.places + (r -> c -> p)
p = X implies xturn[b]
p = O implies oturn[b]
}
pred move2[b: Board, r,c: Index, p: Player, b': Board] {
b'.places = b.places + (r -> c -> p)
p = X implies xturn[b]
p = O implies oturn[b]
}
run move for 2 Board, 5 int
pred differentmoves {
some b: Board, r, c: Index, p: Player, b': Board | {
not (move[b, r, c, p, b'] iff move2[b, r, c, p, b'])
//b.places != b'.places
}
}
run differentmoves for 2 Board, 5 int
pred bothTurn {
some b: Board | {
xturn[b]
oturn[b]
}
}
run bothTurn for 1 Board, 5 int
pred NOTxwinimpliesoturn {
some b: Board | {
(xturn[b] or oturn[b])
not (winning[b, X] implies oturn[b])
}
}
run NOTxwinimpliesoturn for 1 Board, 5 int