在合金中建模TicTacToe

时间:2013-12-02 12:43:19

标签: alloy

如何编写一个谓词来检查合金中tictactoe游戏的水平,垂直或对角线胜利?我有点挣扎下面的语法是我的代码:

open util/ordering [Time] as T

sig Time {}

abstract sig Game {
  turn, winner, loser: Game
}

abstract sig Player {
  opponent:Player
}

sig X extends Player {}
sig O extends Player {}

fact {  
  all t:Time| all p: Player | no p.opponent
  all t: Time | all p: Player | all g:Game | one g.turn
  all t:Time | all g:Game | one g.winner & g.loser
} 

pred HorizontalWin {

}

1 个答案:

答案 0 :(得分:4)

我认为你的模型可能不适合这个游戏。例如,我在模型中没有看到3x3网格,因此不清楚如何表达有关游戏状态的任何属性。

您的模型还有其他几个问题。例如,Game sig是抽象的,并且没有具体的子集,因此该模型的实例永远不能包含任何游戏(因此turnwinnerloser字段也总是空的)。此外,您可能希望在某处使用Time签名(或者在其中放置一些字段,或者让其他字段使用它,例如turn: Player -> Time)然后添加关于每两个连续时间步骤的一些事实正确连接游戏动作。这是一个想法:

open util/ordering [Move] as M

abstract sig Player {}
one sig X, O extends Player {}

abstract sig Cell {}
one sig C00, C01, C02, C10, C11, C12, C20, C21, C22 extends Cell {}

sig Board {
  grid: Cell -> lone Player
} 

sig Move {
  player: Player,
  pos: Cell,
  board, board': Board // pre and post board
} {
  // must choose an empty grid cell
  no board.grid[pos]
  // set the `pos` cell to `player`
  board'.grid[pos] = player
  // all other grid cells remain the same
  all c: Cell - pos | board'.grid[c] = board.grid[c]
}

fact {
  // empty board at the beginning
  no M/first.board.grid
  all m: Move {
    some M/next[m] => {
      // alternate players each move
      M/next[m].player != m.player
      // connect boards
      M/next[m].board = m.board'
    }
  }
}


run {} for 9 but 10 Board