|
|
@ -9,11 +9,11 @@ import Foundation
|
|
|
|
import DouShouQiModel
|
|
|
|
import DouShouQiModel
|
|
|
|
import SpriteKit
|
|
|
|
import SpriteKit
|
|
|
|
import SwiftUI
|
|
|
|
import SwiftUI
|
|
|
|
// Gestion de la boucle de jeu par la création d'une tache async<
|
|
|
|
|
|
|
|
// On s'abonne aux événements, notament game.addPlayerNotifiedListeneren.
|
|
|
|
|
|
|
|
// Les joueurs n'ont besoin que de nom
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* GameVM
|
|
|
|
|
|
|
|
* Cette classe est utilisée pour gérer la logique du jeu
|
|
|
|
|
|
|
|
*/
|
|
|
|
class GameVM : ObservableObject, Identifiable {
|
|
|
|
class GameVM : ObservableObject, Identifiable {
|
|
|
|
|
|
|
|
|
|
|
|
@Published var game: Game
|
|
|
|
@Published var game: Game
|
|
|
@ -21,21 +21,12 @@ class GameVM : ObservableObject, Identifiable {
|
|
|
|
@Published var gameScene: GameScene
|
|
|
|
@Published var gameScene: GameScene
|
|
|
|
@Published var isGameOver: Bool = false
|
|
|
|
@Published var isGameOver: Bool = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///Players (-game -> todelete)
|
|
|
|
|
|
|
|
// let player1 : Player
|
|
|
|
|
|
|
|
// let player2 : Player
|
|
|
|
|
|
|
|
// var pieces : [ Owner : [Animal : SpriteMeeple]]
|
|
|
|
|
|
|
|
// let actualRules : Rules
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///Error
|
|
|
|
///Error
|
|
|
|
@Published var hasError : Bool = false
|
|
|
|
@Published var hasError : Bool = false
|
|
|
|
|
|
|
|
|
|
|
|
///Message
|
|
|
|
///Message
|
|
|
|
@Published var displayMessage : String = ""
|
|
|
|
@Published var displayMessage : String = ""
|
|
|
|
|
|
|
|
|
|
|
|
//On donne directement la scene et la game à la vm
|
|
|
|
|
|
|
|
public init(withGame _game : Game, andScene _gameScene : GameScene) {
|
|
|
|
public init(withGame _game : Game, andScene _gameScene : GameScene) {
|
|
|
|
|
|
|
|
|
|
|
|
self.game = _game
|
|
|
|
self.game = _game
|
|
|
@ -52,23 +43,22 @@ class GameVM : ObservableObject, Identifiable {
|
|
|
|
|
|
|
|
|
|
|
|
self.subscribesToMeeple()
|
|
|
|
self.subscribesToMeeple()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///Lancement du jeu
|
|
|
|
Task{
|
|
|
|
Task{
|
|
|
|
try! await self.game.start()
|
|
|
|
try! await self.game.start()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Début du jeu
|
|
|
|
func onGameStart(board : Board){
|
|
|
|
func onGameStart(board : Board){
|
|
|
|
displayMessage = "==>> 🎉 GAME STARTS! 🎉 <<=="
|
|
|
|
displayMessage = "==>> 🎉 GAME STARTS! 🎉 <<=="
|
|
|
|
self.gameScene.displayBoard(board)
|
|
|
|
self.gameScene.displayBoard(board)
|
|
|
|
print("GAME STARTS")
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Notification du joueur
|
|
|
|
func onPlayerNotified(board : Board, player : Player) async{
|
|
|
|
func onPlayerNotified(board : Board, player : Player) async{
|
|
|
|
print("PLAYER NOTIFIED")
|
|
|
|
|
|
|
|
if player is HumanPlayer {
|
|
|
|
if player is HumanPlayer {
|
|
|
|
displayMessage = "Player \(player.id == .player1 ? "🟡 1" : "🔴 2") - \(player.name), it's your turn!"
|
|
|
|
displayMessage = "Player \(player.id == .player1 ? "🟡 1" : "🔴 2") - \(player.name), it's your turn!"
|
|
|
|
//try! await (player as! HumanPlayer).chooseMove(move)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
do{
|
|
|
|
do{
|
|
|
@ -80,6 +70,7 @@ class GameVM : ObservableObject, Identifiable {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Mouvement choisi
|
|
|
|
func onMoveChosen(board : Board, move : Move, player : Player){
|
|
|
|
func onMoveChosen(board : Board, move : Move, player : Player){
|
|
|
|
///Récupération du Meeple :
|
|
|
|
///Récupération du Meeple :
|
|
|
|
let movedPiece = board.grid[move.rowOrigin][move.columnOrigin]
|
|
|
|
let movedPiece = board.grid[move.rowOrigin][move.columnOrigin]
|
|
|
@ -98,40 +89,16 @@ class GameVM : ObservableObject, Identifiable {
|
|
|
|
|
|
|
|
|
|
|
|
if result { ///* invalidité terminante
|
|
|
|
if result { ///* invalidité terminante
|
|
|
|
if let piece = board.grid[move.rowDestination][move.columnDestination].piece{
|
|
|
|
if let piece = board.grid[move.rowDestination][move.columnDestination].piece{
|
|
|
|
// Delete le meeple
|
|
|
|
|
|
|
|
let meeples = gameScene.pieces[player.id == .player1 ? .player2 : .player1]
|
|
|
|
let meeples = gameScene.pieces[player.id == .player1 ? .player2 : .player1]
|
|
|
|
let meeple = meeples?.first(where: {
|
|
|
|
let meeple = meeples?.first(where: {
|
|
|
|
$0.key == piece.animal
|
|
|
|
$0.key == piece.animal
|
|
|
|
})
|
|
|
|
})
|
|
|
|
meeple?.value.parent?.removeChildren(in: [meeple!.value])
|
|
|
|
meeple?.value.parent?.removeChildren(in: [meeple!.value])
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let piece = board.grid[move.rowOrigin][move.columnOrigin]
|
|
|
|
|
|
|
|
let meeples = gameScene.pieces[move.owner]
|
|
|
|
|
|
|
|
let meeple = meeples?.first(where: {
|
|
|
|
|
|
|
|
$0.key == piece.piece?.animal
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
meeple?.value.cellPosition = CGPoint(x: move.rowOrigin, y: move.columnOrigin);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("INVALID")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func invalideMoveChosen(board: Board, move: Move, player: Player, result: Bool) {
|
|
|
|
///* invalidité non terminante
|
|
|
|
if result {
|
|
|
|
|
|
|
|
if let piece = board.grid[move.rowDestination][move.columnDestination].piece{
|
|
|
|
|
|
|
|
// Delete le meeple
|
|
|
|
|
|
|
|
let meeples = gameScene.pieces[player.id == .player1 ? .player2 : .player1]
|
|
|
|
|
|
|
|
let meeple = meeples?.first(where: {
|
|
|
|
|
|
|
|
$0.key == piece.animal
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
meeple?.value.parent?.removeChildren(in: [meeple!.value])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let piece = board.grid[move.rowOrigin][move.columnOrigin]
|
|
|
|
let piece = board.grid[move.rowOrigin][move.columnOrigin]
|
|
|
|
let meeples = gameScene.pieces[move.owner]
|
|
|
|
let meeples = gameScene.pieces[move.owner]
|
|
|
|
let meeple = meeples?.first(where: {
|
|
|
|
let meeple = meeples?.first(where: {
|
|
|
@ -141,19 +108,19 @@ class GameVM : ObservableObject, Identifiable {
|
|
|
|
meeple?.value.cellPosition = CGPoint(x: move.rowOrigin, y: move.columnOrigin);
|
|
|
|
meeple?.value.cellPosition = CGPoint(x: move.rowOrigin, y: move.columnOrigin);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///Changement de plateau
|
|
|
|
func onBoardChanged(board : Board){
|
|
|
|
func onBoardChanged(board : Board){
|
|
|
|
/// Bruit d'un placement de pion ?
|
|
|
|
/// Bruit d'un placement de pion ?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///Fin du jeu
|
|
|
|
func onGameOver(board : Board, result : Result, winner : Player?){
|
|
|
|
func onGameOver(board : Board, result : Result, winner : Player?){
|
|
|
|
displayMessage = "Game Over!!!"
|
|
|
|
displayMessage = "Game Over!!!"
|
|
|
|
isGameOver = true ///Gestion par l'appelant
|
|
|
|
isGameOver = true ///Gestion par l'appelant
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///*Meeples
|
|
|
|
///Meeples
|
|
|
|
///Abonnement aux mouvements des Meeples
|
|
|
|
|
|
|
|
|
|
|
|
func subscribesToMeeple(){
|
|
|
|
func subscribesToMeeple(){
|
|
|
|
for meeple in gameScene.pieces[.player1]!{
|
|
|
|
for meeple in gameScene.pieces[.player1]!{
|
|
|
|
meeple.value.observers.append(meepleMoved)
|
|
|
|
meeple.value.observers.append(meepleMoved)
|
|
|
@ -163,13 +130,13 @@ class GameVM : ObservableObject, Identifiable {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///*Mouvement d'un Meeple
|
|
|
|
func meepleMoved(spriteMeeple: SpriteMeeple, startX: Int, startY: Int, endX: Int, endY: Int) async{
|
|
|
|
func meepleMoved(spriteMeeple: SpriteMeeple, startX: Int, startY: Int, endX: Int, endY: Int) async{
|
|
|
|
let owner : Owner = game.board.grid[startX][startY].piece!.owner
|
|
|
|
let owner : Owner = game.board.grid[startX][startY].piece!.owner
|
|
|
|
let otherPlayer : Owner = self.game.rules.getNextPlayer()
|
|
|
|
let otherPlayer : Owner = self.game.rules.getNextPlayer()
|
|
|
|
|
|
|
|
|
|
|
|
let move: Move = Move(of: owner, fromRow: startX, andFromColumn: startY, toRow: endX, andToColumn: endY)
|
|
|
|
let move: Move = Move(of: owner, fromRow: startX, andFromColumn: startY, toRow: endX, andToColumn: endY)
|
|
|
|
if(otherPlayer != owner){ ///Mauvais Joueur pour ce jeton
|
|
|
|
if(otherPlayer != owner){ ///Mauvais Joueur pour ce jeton
|
|
|
|
print("invalide de la part de meepleMoved")
|
|
|
|
|
|
|
|
onInvalidMove(board: game.board, move: move, player: game.players[otherPlayer]!, result: false)
|
|
|
|
onInvalidMove(board: game.board, move: move, player: game.players[otherPlayer]!, result: false)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -177,12 +144,10 @@ class GameVM : ObservableObject, Identifiable {
|
|
|
|
if let player: HumanPlayer = game.players[owner] as? HumanPlayer{
|
|
|
|
if let player: HumanPlayer = game.players[owner] as? HumanPlayer{
|
|
|
|
try! await player.chooseMove(move)
|
|
|
|
try! await player.chooseMove(move)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// else { ///IMPOSSIBLE DE CAST LE JOUEUR HUMAIN
|
|
|
|
// else { ///! IMPOSSIBLE DE CAST LE JOUEUR HUMAIN ==> SIGABRT
|
|
|
|
// let player: HumanPlayer = game.players[.player1] as! HumanPlayer
|
|
|
|
// let player: HumanPlayer = game.players[.player1] as! HumanPlayer
|
|
|
|
// try! await player.chooseMove(move)
|
|
|
|
// try! await player.chooseMove(move)
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
print("il a bougé")
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|