You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
6.3 KiB
189 lines
6.3 KiB
//
|
|
// GameVM.swift
|
|
// DouShouQiIOS
|
|
//
|
|
// Created by Pierre FERREIRA on 12/06/2024.
|
|
//
|
|
|
|
import Foundation
|
|
import DouShouQiModel
|
|
import SpriteKit
|
|
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
|
|
|
|
|
|
class GameVM : ObservableObject, Identifiable {
|
|
|
|
@Published var game: Game
|
|
|
|
@Published var gameScene: GameScene
|
|
@Published var isGameOver: Bool = false
|
|
|
|
|
|
|
|
///Players (-game -> todelete)
|
|
// let player1 : Player
|
|
// let player2 : Player
|
|
// var pieces : [ Owner : [Animal : SpriteMeeple]]
|
|
// let actualRules : Rules
|
|
|
|
///Error
|
|
@Published var hasError : Bool = false
|
|
|
|
///Message
|
|
@Published var displayMessage : String = ""
|
|
|
|
//On donne directement la scene et la game à la vm
|
|
public init(withGame _game : Game, andScene _gameScene : GameScene) {
|
|
|
|
self.game = _game
|
|
self.gameScene = _gameScene
|
|
|
|
///Abonnement aux événements
|
|
self.game.addGameStartedListener(onGameStart)
|
|
self.game.addPlayerNotifiedListener(onPlayerNotified)
|
|
self.game.addMoveChosenCallbacksListener(onMoveChosen)
|
|
self.game.addInvalidMoveCallbacksListener(onInvalidMove)
|
|
self.game.addBoardChangedListener(onBoardChanged)
|
|
self.game.addGameOverListener(onGameOver)
|
|
//self.game?.addGameChangedListener({}) - //? cas persistance
|
|
|
|
self.subscribesToMeeple()
|
|
|
|
Task{
|
|
try! await self.game.start()
|
|
}
|
|
}
|
|
|
|
|
|
func onGameStart(board : Board){
|
|
displayMessage = " ==>> 🎉 GAME STARTS! 🎉 <<== "
|
|
self.gameScene.displayBoard(board)
|
|
print("GAME STARTS")
|
|
}
|
|
|
|
func onPlayerNotified(board : Board, player : Player) async{
|
|
print("PLAYER NOTIFIED")
|
|
if player is HumanPlayer {
|
|
displayMessage = "Player \(player.id == .player1 ? "🟡 1" : "🔴 2") - \(player.name), it's your turn!"
|
|
//try! await (player as! HumanPlayer).chooseMove(move)
|
|
}
|
|
else {
|
|
do{
|
|
_ = try await player.chooseMove(in: board, with: self.game.rules)
|
|
}
|
|
catch{
|
|
hasError = true
|
|
}
|
|
}
|
|
}
|
|
|
|
func onMoveChosen(board : Board, move : Move, player : Player){
|
|
///Récupération du Meeple :
|
|
let movedPiece = board.grid[move.rowOrigin][move.columnOrigin]
|
|
let meeples = gameScene.pieces[move.owner]
|
|
|
|
let meeple = meeples?.first(where: {
|
|
$0.key == movedPiece.piece?.animal
|
|
})
|
|
meeple?.value.cellPosition = CGPoint(x: move.rowDestination, y: move.columnDestination)
|
|
|
|
}
|
|
|
|
///Mouvement invalide
|
|
func onInvalidMove(board : Board, move : Move, player : Player, result : Bool){
|
|
displayMessage = "⚠️⚠️⚠️⚠️ Invalid Move detected: \(move) by \(player.name) (\(player.id))"
|
|
|
|
if result { ///* invalidité terminante
|
|
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 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) {
|
|
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 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);
|
|
}
|
|
|
|
|
|
func onBoardChanged(board : Board){
|
|
/// Bruit d'un placement de pion ?
|
|
}
|
|
|
|
func onGameOver(board : Board, result : Result, winner : Player?){
|
|
displayMessage = "Game Over!!!"
|
|
isGameOver = true ///Gestion par l'appelant
|
|
}
|
|
|
|
|
|
///Meeples
|
|
|
|
func subscribesToMeeple(){
|
|
for meeple in gameScene.pieces[.player1]!{
|
|
meeple.value.observers.append(meepleMoved)
|
|
}
|
|
for meeple in gameScene.pieces[.player2]!{
|
|
meeple.value.observers.append(meepleMoved)
|
|
}
|
|
}
|
|
|
|
func meepleMoved(spriteMeeple: SpriteMeeple, startX: Int, startY: Int, endX: Int, endY: Int) async{
|
|
let owner : Owner = game.board.grid[startX][startY].piece!.owner
|
|
let otherPlayer : Owner = self.game.rules.getNextPlayer()
|
|
|
|
let move: Move = Move(of: owner, fromRow: startX, andFromColumn: startY, toRow: endX, andToColumn: endY)
|
|
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)
|
|
return
|
|
}
|
|
|
|
if let player: HumanPlayer = game.players[owner] as? HumanPlayer{
|
|
try! await player.chooseMove(move)
|
|
}
|
|
// else { ///IMPOSSIBLE DE CAST LE JOUEUR HUMAIN
|
|
// let player: HumanPlayer = game.players[.player1] as! HumanPlayer
|
|
// try! await player.chooseMove(move)
|
|
// }
|
|
|
|
print("il a bougé")
|
|
}
|
|
|
|
}
|