-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
…rocess-game-2 Feature/#68 implement process game 2
- Loading branch information
Showing
4 changed files
with
191 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,77 @@ | ||
// import { time } from 'console'; | ||
import { AnimalNames } from '../Enums/AnimalNamesEnum'; | ||
import { Player } from '../Player'; | ||
import { BreedProcessor } from './BreedProcessor'; | ||
import { Bank } from './logic/Bank'; | ||
import { Timer } from './Timer'; | ||
import { GameProcessor } from './logic/GameProcessor'; | ||
import { View } from './View'; | ||
import { Game } from './logic/Game'; | ||
import { defaultGameConfiguration } from './logic/defaultGameConfiguration'; | ||
|
||
export class GameController { | ||
private currentPlayer: Player | undefined; | ||
private player: Player | undefined; | ||
private timer: Timer; | ||
private breedProcessor: BreedProcessor; | ||
private game: Game; | ||
private gameProcessor: GameProcessor; | ||
constructor(private view: View) { | ||
this.timer = new Timer(); | ||
this.breedProcessor = new BreedProcessor(new Bank()); | ||
this.game = new Game(defaultGameConfiguration); | ||
this.gameProcessor = new GameProcessor(this.game); | ||
} | ||
|
||
get theCurrentPlayer(): Player { | ||
return this.currentPlayer as Player; | ||
get theGame(): Game { | ||
return this.game; | ||
} | ||
|
||
get theTimer(): Timer { | ||
return this.timer; | ||
/** | ||
* Starts the turn for the current player. | ||
* Displays alert when the time is over. | ||
* Updates the remaining time on the View. | ||
*/ | ||
startTurn(): void { | ||
this.gameProcessor.startTurn( | ||
(currentPlayer) => { | ||
this.view.displayAlert(currentPlayer?.theName as string); | ||
}, | ||
(remainingTime) => { | ||
this.view.updateRemainingTime(remainingTime); | ||
}, | ||
); | ||
} | ||
|
||
startTurn(): void { | ||
this.timer.countdown(); | ||
const turnTimer = setInterval(() => { | ||
if (!this.timer.running) { | ||
clearInterval(turnTimer); | ||
if (Math.ceil(this.timer.theTurnTimeLeft) === 0) { | ||
this.view.displayAlert( | ||
this.currentPlayer?.theName as string, | ||
); | ||
this.nextPlayer(); | ||
this.startTurn(); | ||
} | ||
} | ||
this.view.updateRemainingTime( | ||
Math.round(this.timer.theTurnTimeLeft), | ||
); | ||
}, 10); | ||
stopTurn(): void { | ||
this.gameProcessor.stopTurn(); | ||
} | ||
|
||
breed(): [AnimalNames, AnimalNames] | undefined { | ||
if (this.timer.theTurnTimeLeft === 0) { | ||
return; | ||
/** | ||
* Executes trade proposed by the player and checks win condition. | ||
* If player wins the game after the trade, stops the timer and tells the View to display the WinModal. | ||
* @param offer made by the player | ||
* @param target desired by the player | ||
* @returns true if the trade was sucessful, false otherwise | ||
*/ | ||
trade( | ||
offer: [AnimalNames, number], | ||
target: [AnimalNames, number], | ||
): boolean { | ||
const tradeResult = this.gameProcessor.trade(offer, target); | ||
if (this.gameProcessor.checkWin()) { | ||
this.gameProcessor.stopTurn(); | ||
this.view.displayWinModal(this.game.theCurrentPlayer); | ||
} | ||
const rollResult = this.breedProcessor.processBreedPhase( | ||
this.currentPlayer as Player, | ||
); | ||
return rollResult; | ||
return tradeResult; | ||
} | ||
|
||
stopTurn(): void { | ||
this.timer.resetTurn(); | ||
/** | ||
* Rolls the dice for the player and updates their Herd. | ||
* If player wins the game after the breed, stops the timer and tells the View to display the WinModal. | ||
*/ | ||
breed(): [AnimalNames, AnimalNames] | undefined { | ||
const diceResult = this.gameProcessor.breed(); | ||
if (this.gameProcessor.checkWin()) { | ||
this.gameProcessor.stopTurn(); | ||
this.view.displayWinModal(this.game.theCurrentPlayer); | ||
} | ||
return diceResult; | ||
} | ||
|
||
/** | ||
* Sets the current player to the next player in order. | ||
*/ | ||
nextPlayer(): void { | ||
//TODO multiplayer logic | ||
this.currentPlayer = this.player; | ||
this.timer.resetTurn(); | ||
this.gameProcessor.nextPlayer(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import { AnimalNames } from '~src/Enums/AnimalNamesEnum'; | ||
import { Player } from '~src/Player'; | ||
import { Game } from './Game'; | ||
|
||
export class GameProcessor { | ||
constructor(private game: Game) {} | ||
|
||
/** | ||
* Starts the timer for current players turn. | ||
* When the time is over, resets the timer, sets current player to the next player and starts the timer. | ||
* @param turnTimeOverCallback to be executed when the time is over | ||
* @param updateRemainingTimeCallback to be executed when the remaining time changes | ||
*/ | ||
startTurn( | ||
turnTimeOverCallback: (currentPlayer: Player) => void, | ||
updateRemainingTimeCallback: (remainingTime: number) => void, | ||
): void { | ||
this.game.theTimer.countdown(); | ||
const turnTimer = setInterval(() => { | ||
if (!this.game.theTimer.running) { | ||
clearInterval(turnTimer); | ||
if (Math.ceil(this.game.theTimer.theTurnTimeLeft) === 0) { | ||
turnTimeOverCallback(this.game.theCurrentPlayer); | ||
|
||
this.nextPlayer(); | ||
this.startTurn( | ||
turnTimeOverCallback, | ||
updateRemainingTimeCallback, | ||
); | ||
} | ||
} | ||
updateRemainingTimeCallback( | ||
Math.round(this.game.theTimer.theTurnTimeLeft), | ||
); | ||
}, 10); | ||
} | ||
|
||
/** | ||
* Stops the timer for the current player. | ||
*/ | ||
stopTurn(): void { | ||
this.game.theTimer.resetTurn(); | ||
} | ||
|
||
/** | ||
* Executes trade proposed by the player and checks win condition. | ||
* @param offer made by the player | ||
* @param target desired by the player | ||
* @returns true if the trade was sucessful, false if the trade was not sucessful or the player run out of time | ||
*/ | ||
trade( | ||
offer: [AnimalNames, number], | ||
target: [AnimalNames, number], | ||
): boolean { | ||
if (!this.hasTimeLeft()) { | ||
return false; | ||
} | ||
const tradeResult = this.game.theTrade.processOffer( | ||
offer, | ||
this.game.theCurrentPlayer, | ||
target, | ||
); | ||
return tradeResult; | ||
} | ||
|
||
/** | ||
* @returns true if current player wins the game, false otherwise | ||
*/ | ||
checkWin(): boolean { | ||
const animalsRequiredToWin: AnimalNames[] = [ | ||
AnimalNames.RABBIT, | ||
AnimalNames.SHEEP, | ||
AnimalNames.PIG, | ||
AnimalNames.COW, | ||
AnimalNames.HORSE, | ||
]; | ||
for (const animal in animalsRequiredToWin) { | ||
if ( | ||
this.game.theCurrentPlayer.theHerd.getAnimalNumber( | ||
animal as AnimalNames, | ||
) === 0 | ||
) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Rolls the dice for the player and updates their Herd. | ||
* @returns the result of the current players roll | ||
*/ | ||
breed(): [AnimalNames, AnimalNames] | undefined { | ||
if (!this.hasTimeLeft()) { | ||
return; | ||
} | ||
const rollResult = this.game.theBreedProcessor.processBreedPhase( | ||
this.game.theCurrentPlayer, | ||
); | ||
return rollResult; | ||
} | ||
|
||
/** | ||
* Sets the current player to the next player in order and resets the timer. | ||
*/ | ||
nextPlayer(): void { | ||
this.game.nextPlayer(); | ||
this.game.theTimer.resetTurn(); | ||
} | ||
|
||
private hasTimeLeft(): boolean { | ||
return this.game.theTimer.theTurnTimeLeft === 0; | ||
} | ||
} |