+ {dumbStupidVariable}
- {buttons2}
+ {/*buttons2 are summoning buttons */}
{/*Gonna need to comment much of this just so we're aware of what is happening in some of these.*/}
{/*This div is a row that shows a players stats and then their hand of cards*/}
+ {/*rendered in a seperate div so they'll be in a row*/}
-
+
{buttons2}
{/*This div pretty large. It's where discard piles, decks, and the actual board goes*/}
-
+
+
+ {/*the magnified card*/}
+
{/*This column shows a deck and discard pile*/}
{/*The board between two columns*/}
-
+
{/*This is a row of two columns*/}
{/*The first column shows the deck and discard pile (like the one you saw earlier*/}
{/*This column shows the game log text bot and the button for moving phases below it*/}
@@ -481,19 +592,33 @@ function GameBoard({ game, setGameState }: { game: Game, setGameState: React.Dis
{buttons1}
-
+
);
}
-
-function SummoningButtons({cardPos, game, setSummonState, hand, setGame, playerid}: {cardPos: number, game: Game, setSummonState: any,
- hand: Card[], setGame: any, playerid: number}){
-
+/**
+ * @author Tanner Brown
+ * I always thought it was weird that common practice was to put an author on these. Like, I get its so down the line someone can call you up and be like
+ * "why does your code suck?", but I can't shake the feeling like I'm a child writing my name on my toys so no one else can play with them.
+ *
+ * Anyways, summoning buttons are the buttons that render when we're summoning a card. 4 buttons show up; one for each zone.
+ * @param cardPos: the position in hand the card we're summoning is. game: the game object. setSummonState: the state that controls when the buttons are rendering.
+ * marked -1 to make buttons disappear after we summon. playerid: the id of the player who will be summoning the card. log/setLog: the log the game keeps
+ * and the function to update it
+ * @returns markup for summoning buttons
+ */
+function SummoningButtons({cardPos, game, setSummonState, playerid, log, setLog}: {cardPos: number, game: Game, setSummonState: any,
+ board: any, playerid: number, log: any, setLog: any}){
function handle(boardPos: number, playerid: number){
- game.summonCardFromHand(playerid,boardPos, cardPos)
- setGame(game);
+ let name = game.summonCardFromHand(playerid,boardPos, cardPos)
+ if(name){
+ setLog([...log,
{game.getPlayerById(playerid).username} summoned the "{name}" at zone {boardPos+1}
])
+ }
+ else{
+ setLog([...log,
{game.getPlayerById(playerid).username} attempted to summon a creature, but lacks the actions
])
+ }
setSummonState(-1);
}
return(
@@ -511,15 +636,26 @@ function SummoningButtons({cardPos, game, setSummonState, hand, setGame, playeri
handle(3, playerid);
}}>Zone 4
-
)
}
-function AttackingButtons({player, game, setGame}: {player: Player, game: Game, setGame: any}){
+/**
+ * @author Tanner Brown
+ *
+ * These are the buttons that show up during battle phase and let you attack. if an attack kills the opponent then we alert and reset the game
+ * @param player: the player who will be attacking. game: the game object. reset/setReset: variable and function for controlling re-render. setbegin: need this
+ * to return to deck select screen
+ * @returns mark up for attacking buttons
+ */
+function AttackingButtons({player, game, reset, resetState, setBegin}: {player: Player, game: Game, reset: number, resetState: any, setBegin: any}){
let playerid = player.id;
function handle(boardPos: number, playerid: number){
game.simulateCombat(boardPos, playerid);
- setGame(game);
+ if(game.getOtherPlayer(player.id).hp <= 0){
+ alert(`${player.username} has won. Press OK to return to deck select screen.`);
+ setBegin(false);
+ }
+ resetState(dumbStupidFunction(reset));
}
return (
@@ -538,36 +674,43 @@ function AttackingButtons({player, game, setGame}: {player: Player, game: Game,
)
}
+
+
+
/**
* has a block of scrollable text showing player actions and shows turn and phase
* @returns markup that displays the gamelog in the browser
*/
function GameLog({
- game,
- setGame
+ turn,
+ phase,
+ currentPlayer,
+ log
}: {
- game: Game,
- setGame: any
+ turn: number;
+ phase: number;
+ currentPlayer: Player;
+ log: any
}) {
let phaseName;
- if(game.turnPhase==0){
+ if(phase==0){
phaseName="Main phase";
}
- else if(game.turnPhase==1){
+ else if(phase==1){
phaseName="Battle phase";
}
- else if(game.turnPhase==2){
+ else if(phase==2){
phaseName="End phase";
}
return (
<>
{log}
- Turn: {game.turnPhase}
+ Turn: {turn}
Phase: {phaseName}
- Turn Player: {game.currentPlayer.username}
+ Turn Player: {currentPlayer.username}test
>
);
@@ -579,18 +722,24 @@ function GameLog({
function PhaseButton({
game,
imagePath,
- setGame,
+ setPhase,
+ setTurn,
+ setCurrentPlayer,
setSummoning
}: {
game: Game;
imagePath: string;
- setGame: any,
+ setPhase: React.Dispatch
>;
+ setTurn: React.Dispatch>;
+ setCurrentPlayer: React.Dispatch>;
setSummoning: React.Dispatch>
}) {
function handle() {
game.enterNextPhase();
- setGame(game);
+ setPhase(game.turnPhase);
+ setTurn(game.currentTurn);
setSummoning(-1);
+ setCurrentPlayer(game.currentPlayer);
}
return (
@@ -600,15 +749,16 @@ function PhaseButton({
}
function App() {
const [begin, setBegin] = useState(false);
- const [game, setGame] = useState(new Game());
let h = function () {
setBegin(true);
};
+
let page = <>>;
if (begin) {
+ let game = new Game();
getDemoPlayer(game.getPlayerById(0))
getDemoPlayer(game.getPlayerById(1))
- page = ;
+ page = ;
} else {
page = ;
}
@@ -629,7 +779,7 @@ function ListOfDecks() {
);
}
-function DeckSelectScreen({ handle }: { handle: Function }) {
+function DeckSelectScreen({ handle }: { handle: any }) {
return (
CARD BATTLES
@@ -641,3 +791,12 @@ function DeckSelectScreen({ handle }: { handle: Function }) {
);
}
+
+function dumbStupidFunction(r: number){
+ if(r==0){
+ return 1;
+ }
+ else{
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/src/engine/CardMap.ts b/src/engine/CardMap.ts
index a104eb9..715cc3f 100644
--- a/src/engine/CardMap.ts
+++ b/src/engine/CardMap.ts
@@ -1,13 +1,7 @@
import {
- LandscapeType,
- Targeter,
- PlayerTargeter,
- LaneTargeter,
- TargetType,
- BoardPos,
- Game,
+ LandscapeType
} from "../model.ts";
-import { Card, Creature, Landscape } from "./card.ts";
+import { Card, Creature } from "./card.ts";
var cardMap: Map = new Map();
@@ -38,6 +32,14 @@ export function get(name: string): Card {
//=====================================================================================================================================================
// CREATURES
//=====================================================================================================================================================
+
+//Swamp Creatures
+
+
+//Made this card more for testing or ending the game quickly if we have to.
+put(
+ "Swamp Dragon",new Creature("Swamp Dragon","",2,LandscapeType.Swamp,25,8)
+);
put(
"Dark Angel",
new Creature(
@@ -45,7 +47,7 @@ put(
"",
1,
LandscapeType.Swamp,
- 0,
+ 10,
5,
),
);
@@ -54,17 +56,7 @@ put(
"Bog Bum",
new Creature("Bog Bum", "", 1, LandscapeType.Swamp, 2, 6),
);
-put(
- "Music Mallard",
- new Creature(
- "Music Mallard",
- "",
- 1,
- LandscapeType.Candylands,
- 0,
- 9,
- ),
-);
+
// Not sure about this one. This card's ability is not really functional right now.
put(
@@ -88,6 +80,91 @@ put(
new Creature("Man Witch", "", 2, LandscapeType.Swamp, 4, 4),
);
+
+
+put(
+ "Ban-She Princess",new Creature("Ban She Princess","",1,LandscapeType.Swamp,2,7)
+);
+put(
+ "Ban-She Queen",new Creature("Ban She Queen","",2,LandscapeType.Swamp,4,9)
+);
+
+put(
+ "Ban-She Knight",new Creature("Ban She Knight","",1,LandscapeType.Swamp,3,7)
+);
+put(
+ "Black Merlock",new Creature("Black Merlock","",1,LandscapeType.Swamp,2,5)
+);
+
+put(
+ "Bog Ban-She Angel",new Creature("Bog Ban-She Angel","",1,LandscapeType.Swamp,2,7)
+);
+put(
+ "Eye Dude",new Creature("Eye Dude","",1,LandscapeType.Swamp,2,9)
+);
+
+put(
+ "Giant Spider",new Creature("Giant Spider","",2,LandscapeType.Swamp,4,10)
+);
+put(
+ "Burning Eyebat",new Creature("Burning Eyebat","",1,LandscapeType.Swamp,4,4)
+);
+
+put(
+ "InstiGator",new Creature("GoldenGator","",1,LandscapeType.Swamp,5,2)
+);
+put(
+ "Axe Stump",new Creature("Axe Stump","",1,LandscapeType.Swamp,4,4)
+);
+
+put(
+ "Skeleton Hand",new Creature("Skeleton Hand","",2,LandscapeType.Swamp,1,11)
+);
+put(
+ "Undying Tree",new Creature("Undying Tree","",2,LandscapeType.Swamp,3,8)
+);
+
+put(
+ "InstiGator",new Creature("GoldenGator","",1,LandscapeType.Swamp,5,2)
+);
+put(
+ "Bald Guy",new Creature("Bald Guy","",1,LandscapeType.Swamp,3,2)
+);
+
+put(
+ "",new Creature("The Sludge","The Sludge",1,LandscapeType.Swamp,2,5)
+);
+
+put(
+ "Sludgebob",new Creature("Sludgebob","",1,LandscapeType.Swamp,1,7)
+);
+
+put(
+ "General Mushroom",new Creature("General Mushroom","",1,LandscapeType.Swamp,4,3)
+);
+
+put(
+ "Swamp Beast",new Creature("Swamp Beast","",2,LandscapeType.Swamp,5,8)
+);
+put(
+ "Flying Gator",new Creature("Flying Gator","",2,LandscapeType.Swamp,6,4)
+);
+put(
+ "Orange Slime Monster",new Creature("Orange Slime Monster","",1,LandscapeType.Swamp,5,5)
+);
+
+put(
+ "Green Mermaid",new Creature("Green Mermaid","",1,LandscapeType.Swamp,3,7)
+);
+
+put(
+ "Green Merman",new Creature("Green Merman","",1,LandscapeType.Swamp,0,10)
+);
+
+
+
+//CandyLand Creatures
+
put(
"Furious Hen",
new Creature("Furious Hen", "", 1, LandscapeType.Candylands, 2, 7),
@@ -108,6 +185,18 @@ put(
new Creature("Cottonpult","",2, LandscapeType.Candylands,6,6),
);
+put(
+ "Music Mallard",
+ new Creature(
+ "Music Mallard",
+ "",
+ 1,
+ LandscapeType.Candylands,
+ 0,
+ 9,
+ ),
+);
+
//=====================================================================================================================================================
// SANDYLANDS
//=====================================================================================================================================================
diff --git a/src/engine/card.ts b/src/engine/card.ts
index 5935395..450f63f 100644
--- a/src/engine/card.ts
+++ b/src/engine/card.ts
@@ -21,7 +21,7 @@ export class Card {
imageURL: string = "";
private cost: number;
private isReady: boolean;
- private location: BoardPos | string = CardLocations.Deck;
+ location: BoardPos | string = CardLocations.Deck;
constructor(
name: string,
@@ -36,7 +36,7 @@ export class Card {
this.cost = cost;
this.landscapeType = landscapeType;
this.turnPlayed = Game.getInstance().currentTurn;
- this.isReady = true;
+ this.isReady = false;
}
setImageUrl(URL: string): Card {
@@ -87,14 +87,20 @@ export class Card {
}
play(_target: BoardPos, _playerId: number) {
+ console.log("Calling play(target: BoardPos, playerId: number) in class Card, don't do that!");
this.displayCard();
return false;
}
death() {
+ console.log("Calling death() on " + this.name);
if (this.ownerId != null) {
Game.getInstance().getPlayerById(this.ownerId).discardPile.push(this);
- this.moveCard(CardLocations.Discard);
+ //this.moveCard(CardLocations.Discard); //Doesn't actually move the cards from the board...
+ if(this.location instanceof BoardPos) {
+ console.log(this.name + " has died from lane " + (this.location.posId+1));
+ this.location.removeCreature();
+ }
}
}
@@ -196,6 +202,11 @@ export class Card {
);
}
+ equals(other: Card): boolean {
+ return this.name == other.name && this.flavorText == other.flavorText && this.cardType == other.cardType && this.cost == other.cost
+ && this.landscapeType == other.landscapeType;
+ }
+
//Null Card Constant
static getNull(): Card {
return new Card("Null", "You shouldn't be seeing this!", 99, 0, LandscapeType.NULL);
@@ -222,6 +233,11 @@ export class Creature extends Card {
}
Attack(Target: Creature | Player) {
+ if(!this.getIsReady()) {
+ console.log("Creature not ready!");
+ return false;
+ }
+
if (Target instanceof Creature) {
Target.defense -= this.attack;
if (Target.defense <= 0) {
@@ -231,17 +247,23 @@ export class Creature extends Card {
if (this.defense <= 0) {
this.death();
}
+ this.setIsReady(false);
+ return true;
} else {
Target.hp -= this.attack;
+ this.setIsReady(false);
+ return true;
}
}
override play(pos: BoardPos, playerId: number) {
- if (pos.creature == Creature.getNull()) {
- if(pos.setCreature(this)) {
- Game.getInstance().getPlayerById(playerId).actions -= this.getCost();
- return true;
- }
+ console.log("Playing Creature " + this.name + " at pos " + pos.posId + " on player " + playerId + "'s side of the board");
+ if (pos.creature.name == Creature.getNull().name) {
+ if(pos.setCreature(this)) {
+ this.location = pos;
+ this.ownerId = playerId;
+ return true;
+ }
}
return false;
}
@@ -257,6 +279,11 @@ export class Creature extends Card {
);
}
+ override equals(other: Creature): boolean {
+ return this.name == other.name && this.flavorText == other.flavorText && this.cardType == other.cardType && this.getCost() == other.getCost()
+ && this.landscapeType == other.landscapeType && this.maxDefense == other.maxDefense;
+ }
+
//Creature Constants
static getNull(): Creature {
return new Creature(
@@ -284,6 +311,7 @@ export class Landscape extends Card {
}
override play(pos: BoardPos) {
+ console.log("Playing Landscape " + this.name + " at pos " + pos.posId + " on player " + pos.ownerId + "'s side of the board");
if (pos.landscape == LandscapeType.NULL) {
return pos.setLandscape(this);
}
diff --git a/src/index.css b/src/index.css
index 54183d0..41ca079 100644
--- a/src/index.css
+++ b/src/index.css
@@ -84,12 +84,22 @@
overflow: auto;
flex-direction: column;
border-radius: 0.5rem;
- border-width: 2px;
+ border-width: 3px;
border-color: black;
width: 100px;
height: 150px;
}
+.hover_card_shape {
+ overflow: auto;
+ flex-direction: column;
+ border-radius: 0.5rem;
+ border-width: 3px;
+ border-color: black;
+ width: 200px;
+ height: 300px;
+}
+
.player_display {
overflow: auto;
flex-direction: row;
@@ -134,3 +144,20 @@
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
+
+.player_0 {
+ border-color: darkred;
+}
+
+.player_1 {
+ border-color: darkblue;
+}
+
+
+.text_player_0 {
+ color: darkred;
+}
+
+.text_player_1 {
+ color: darkblue;
+}
\ No newline at end of file
diff --git a/src/model.test.ts b/src/model.test.ts
index bdcc33f..dcf3319 100644
--- a/src/model.test.ts
+++ b/src/model.test.ts
@@ -2,7 +2,7 @@ import { expect, test, assert } from "vitest";
import { Game, AbstractGame, LandscapeType, BoardPos, CardType, Player } from "./model.ts";
import { Card, Creature, Landscape, GetCardTargetEvent } from "./engine/card.ts";
import { get as getCardFromCardMap } from "./engine/CardMap.ts";
-import { GetBoardPosTargetEvent } from "./engine/event.ts";
+import { GetBoardPosTargetEvent, PlayCardEventName, PlayCardEvent } from "./engine/event.ts";
test("new game works", () => {
assert(Game.getInstance() instanceof AbstractGame);
@@ -23,13 +23,15 @@ test("Game is Playable", () => {
getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"),
getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter")];
- assert(deck1.map((card: Card) => {return card != Card.getNull()}));
+ assert(deck1.map((card: Card) => {return card.name != Card.getNull().name}));
var deck2: Card[] = [getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"),
getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"),
getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter")];
- assert(deck2.map((card: Card) => {return card != Card.getNull()}));
+ var tempDeck: Card[] = [getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"),
+ getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"),
+ getCardFromCardMap("Fly Swatter"), getCardFromCardMap("Dark Angel"), getCardFromCardMap("Bog Bum"), getCardFromCardMap("Fly Swatter")];
var swampLand: Landscape = new Landscape("Swamp", "Goopy!", LandscapeType.Swamp);
@@ -37,50 +39,87 @@ test("Game is Playable", () => {
//Game Test
Game.getInstance().addGameEventListener(GetCardTargetEvent, (evt: Event) => {
- console.log("Recieved event with name " + evt.type);
+ //console.log("Recieved event with name " + evt.type);
if(evt instanceof GetBoardPosTargetEvent) {
- console.log("Recieved event of Type GetBoardPosTargetEvent!");
+ //console.log("Recieved event of Type GetBoardPosTargetEvent!");
var player: Player = Game.getInstance().getPlayerById(evt.executorId);
var didExecute = false;
- if(evt.targeter != null) {
- var playerBoard: BoardPos[] | undefined = Game.getInstance().board.getSideByOwnerId(player.id)
- if(typeof(playerBoard) == "undefined") {
- console.log("====PlayerId is incorrect, cannot play card!====");
- }else {
- for(var j = 0; j < playerBoard.length; j++) {
- if(didExecute) {
- return;
- }else {
- didExecute = evt.execute(playerBoard[j]);
- }
+ var playerBoard: BoardPos[] | undefined = Game.getInstance().board.getSideByOwnerId(player.id)
+ if(typeof(playerBoard) == "undefined") {
+ console.log("====PlayerId is incorrect, cannot play card!====");
+ }else {
+ for(var j = 0; j < playerBoard.length; j++) {
+ if(didExecute) {
+ return;
+ }else {
+ didExecute = evt.execute(playerBoard[j]);
}
}
}
}
});
+ Game.getInstance().addGameEventListener(PlayCardEventName, (evt: Event) => {
+ console.log("Recieved PlayCardEvent event with name " + evt.type);
+ // if(evt instanceof PlayCardEvent) {
+ // var board: BoardPos[] | undefined = Game.getInstance().board.getSideByOwnerId(Game.getInstance().getPlayerById(evt.executorId).id);
+ // if(typeof(board) != "undefined") {
+ // for(var i = 0; i < board.length; i++) {
+ // if(evt.card.play(board[i], evt.executorId)) {
+ // break;
+ // }
+ // }
+ // }
+ // }
+ });
+
Game.getInstance().board.getSideByOwnerId(0)?.map((pos: BoardPos) => {pos.setLandscape(swampLand)});
+ Game.getInstance().board.getSideByOwnerId(1)?.map((pos: BoardPos) => {pos.setLandscape(swampLand)});
- var player0Side: BoardPos[] | undefined = Game.getInstance().board.getSideByOwnerId(1);
- expect(typeof player0Side != "undefined" && player0Side[1].landscape == LandscapeType.Swamp);
+ var player0Side: BoardPos[] | undefined = Game.getInstance().board.getSideByOwnerId(0);
+ expect(typeof player0Side != "undefined" && player0Side[0].landscape == LandscapeType.Swamp);
assert(Game.getInstance().currentPlayer == Game.getInstance().getPlayerById(0));
- Game.getInstance().currentPlayer.deck = deck1;
- Game.getInstance().currentPlayer.drawCard(6, false);
+ Game.getInstance().getPlayerById(0).setDeck(deck1);
+ Game.getInstance().getPlayerById(1).setDeck(deck2);
+
+ // console.log("===================================== SHUFFLED DECKS =====================================");
+ // var deck1String = "";
+ // tempDeck.map((card: Card) => {deck1String += (card.name + ", ")});
+ // console.log("Pre-shuffle Deck: {" + deck1String.slice(0, deck1String.length - 2) + "}, length " + tempDeck.length);
+ // deck1String = "";
+ // Game.getInstance().getPlayerById(0).deck.map((card: Card) => {deck1String += (card.name + ", ")});
+ // console.log("Player 1's Deck: {" + deck1String.slice(0, deck1String.length - 2) + "}, length " + Game.getInstance().getPlayerById(0).deck.length);
+ // deck1String = "";
+ // Game.getInstance().getPlayerById(1).deck.map((card: Card) => {deck1String += (card.name + ", ")});
+ // console.log("Player 2's Deck: {" + deck1String.slice(0, deck1String.length - 2) + "}, length " + Game.getInstance().getPlayerById(1).deck.length);
+
+ Game.getInstance().getPlayerById(0).drawCard(6, false);
+ Game.getInstance().getPlayerById(1).drawCard(5, false);
assert(Game.getInstance().currentPlayer.hand.length == 6);
- for(var i = 0; i < 25; i++) {
- console.log("Current player's hand: ");
- Game.getInstance().currentPlayer.hand.map((card: Card) => console.log(card.name))
-
- Game.getInstance().currentPlayer.hand.map((card: Card) => {if(Game.getInstance().currentPlayer.actions >= 0 && card.cardType == CardType.Creature) {
- Game.getInstance().playCard(card, Game.getInstance().currentPlayer.id);
- console.log("Trying to play card " + card.name);
- }});
+ for(var i = 0; i < 50; i++) {
+ console.log("====================================== TURN " + (i+1) + " ======================================");
+ console.log("Game Phase: " + Game.getInstance().turnPhase + ", Actual Game turn: " + (Game.getInstance().currentTurn+1));
+ console.log("My HP: " + Game.getInstance().currentPlayer.hp + ", Their HP: " + Game.getInstance().getOtherPlayer(Game.getInstance().currentPlayer.id).hp);
+ var cardHand = "";
+ Game.getInstance().currentPlayer.hand.map((card: Card) => {cardHand += (card.name + ", ")});
+ console.log("Current player's hand: [" + cardHand.slice(0, cardHand.length - 2) + "]");
+
+ var playerHand: Card[] = Game.getInstance().currentPlayer.hand;
+ for(var j = 0; j < playerHand.length; j++) {
+ var card: Card = playerHand[j];
+ if(Game.getInstance().currentPlayer.actions >= card.getCost() && card.cardType == CardType.Creature) {
+ //console.log("Trying to play card " + card.name);
+ if(Game.getInstance().playCard(card, Game.getInstance().currentPlayer.id)) {
+ //console.log("Trying to play card " + card.name);
+ }
+ }
+ }
- assert(Game.getInstance().currentPlayer.actions >= 0);
+ assert(Game.getInstance().currentPlayer.actions >= 0, "Player Actions left: " + Game.getInstance().currentPlayer.actions);
Game.getInstance().enterNextPhase();
var mySide: BoardPos[] | undefined = Game.getInstance().board.getSideByOwnerId(Game.getInstance().currentPlayer.id);
@@ -88,25 +127,30 @@ test("Game is Playable", () => {
assert(typeof(mySide) != "undefined" && typeof(theirSide) != "undefined");
assert(mySide.length == theirSide.length);
- console.log("My Side");
+
+ var mySideString = "";
for(var j = 0; j < mySide.length; j++) {
- console.log(mySide[j].creature.name + ", ");
+ mySideString += (mySide[j].creature.name + "{A:" + mySide[j].creature.attack + "--D:" + mySide[j].creature.defense + "}" + ", ");
}
+ console.log("My Side: [" + mySideString.slice(0, mySideString.length - 2) + "]");
- console.log("Their Side:");
+ var theirSideString = "";
for(var j = 0; j < theirSide.length; j++) {
- console.log(theirSide[j].creature.name + ", ");
+ theirSideString += (theirSide[j].creature.name + "{A:" + theirSide[j].creature.attack + "--D:" + theirSide[j].creature.defense + "}" + ", ");
}
+ console.log("Their Side: [" + theirSideString.slice(0, theirSideString.length - 2) + "]");
//Do attacks
if(typeof(mySide) != "undefined" && typeof(theirSide) != "undefined") {
for(var j = 0; j < mySide.length; j++) {
var myPos: BoardPos = mySide[j];
var theirPos: BoardPos = theirSide[j];
- if(myPos.creature != Creature.getNull()) {
- if(theirPos.creature == Creature.getNull()) {
+ if(!myPos.creature.equals(Creature.getNull())) {
+ if(!theirPos.creature.equals(Creature.getNull())) {
+ console.log("My " + myPos.creature.name + " is attacking their " + theirPos.creature.name + " in lane " + (myPos.posId+1) + "!");
myPos.creature.Attack(theirPos.creature);
}else {
+ console.log("My " + myPos.creature.name + " is attacking their hero from lane " + myPos.posId + "!");
myPos.creature.Attack(Game.getInstance().getOtherPlayer(Game.getInstance().currentPlayer.id));
}
}
@@ -117,5 +161,7 @@ test("Game is Playable", () => {
console.log("Player " + Game.getInstance().currentPlayer.id + " has won the game!");
break;
}
+
+ Game.getInstance().enterNextPhase();
}
});
\ No newline at end of file
diff --git a/src/model.ts b/src/model.ts
index c8ef3db..523cc2d 100644
--- a/src/model.ts
+++ b/src/model.ts
@@ -1,3 +1,4 @@
+//import { randomInt } from "crypto";
import {
Card,
Creature,
@@ -6,20 +7,18 @@ import {
} from "./engine/card.ts";
import {
GetBoardPosTargetEvent,
- GetPlayerTargetEvent,
PlayCardEvent,
SwitchTurnsEvent,
SwitchTurnPhaseEvent,
DrawCardEvent,
- DiscardCardEvent,
- CardDeathEvent
+ DiscardCardEvent
} from "./engine/event.ts";
//============================================================== Enums ==============================================================
export const TurnPhases = {
Play: 0,
- Action: 1,
- Battle: 2,
+ //Action: 1,
+ Battle: 1,
};
export const LandscapeType = {
@@ -245,6 +244,20 @@ export class Player {
this.cardDiscount = 0;
}
+ setDeck(deck: Card[]) {
+ this.deck = deck;
+ this.shuffleCards();
+ }
+
+ shuffleCards() {
+ for(var i = 0; i < this.deck.length; i++) {
+ var rand1 = randomInt(0, this.deck.length);
+ var temp = this.deck[rand1];
+ this.deck.push(temp);
+ this.deck.splice(rand1, 1);
+ }
+ }
+
discard(index: number = -1) {
if (index == -1) {
index = Math.floor(Math.random() * this.hand.length);
@@ -256,6 +269,15 @@ export class Player {
Game.getInstance().dispatchEvent(new DiscardCardEvent(this.discardPile[discardIndex], this.id));
}
+ discardCard(card: Card) {
+ for(var i = 0; i < this.hand.length; i++) {
+ if(card.equals(this.hand[i])) {
+ this.discard(i);
+ return;
+ }
+ }
+ }
+
drawCard(amount: number, useAction: boolean) {
for (let i = 0; i < amount; i++) {
if (this.deck.length >= 0) {
@@ -285,8 +307,6 @@ export class Player {
}
}
-
-
//============================================================== Board ==============================================================
export class BoardPos {
static boardIdCounter = 0;
@@ -303,7 +323,7 @@ export class BoardPos {
}
setCreature(card: Creature) {
- if (this.creature == Creature.getNull()) {
+ if (this.creature.name == Creature.getNull().name) {
this.creature = card;
return true;
}
@@ -372,7 +392,7 @@ export class AbstractGame extends EventTarget {
super();
}
- addEventListener(
+ addGameEventListener(
_event: string,
_eventCallback: EventListenerOrEventListenerObject,
) {}
@@ -385,13 +405,19 @@ export class AbstractGame extends EventTarget {
return new Player(0);
}
+ getBoard(): SidedBoard {
+ return this.board;
+ }
+
enterNextPhase() {}
switchTurns(_currentPlayerId: number) {}
resetCards(_playerId: number) {}
- playCard(_card: Card, _playerId: number) {}
+ playCard(_card: Card, _playerId: number): boolean {
+ return false;
+ }
}
export class Game extends AbstractGame {
@@ -424,26 +450,27 @@ export class Game extends AbstractGame {
Game.GameInstance = new Game();
}
- getBoard() {
+ override getBoard(): SidedBoard {
return this.board;
}
- addEventListener(
+ override addGameEventListener(
event: string,
eventCallback: EventListenerOrEventListenerObject,
) {
+ console.log("Adding Event Listener for " + event);
this.addEventListener(event, eventCallback);
}
- getPlayerById(playerId: number) {
+ override getPlayerById(playerId: number) {
return this.players[playerId];
}
- getOtherPlayer(playerId: number) {
+ override getOtherPlayer(playerId: number) {
return this.players[(playerId + 1)%this.players.length];
}
- enterNextPhase() {
+ override enterNextPhase() {
this.turnPhase++;
if (this.turnPhase > TurnPhases.Battle) {
this.turnPhase = TurnPhases.Play;
@@ -452,13 +479,22 @@ export class Game extends AbstractGame {
this.dispatchEvent(new SwitchTurnPhaseEvent(this.turnPhase));
}
- switchTurns() {
+ override switchTurns() {
this.currentTurn++;
this.currentPlayer = this.players[this.currentTurn%this.players.length]
this.currentPlayer.actions=2;
+ this.currentPlayer.drawCard(1, false);
this.resetCards(this.currentPlayer.id);
this.dispatchEvent(new SwitchTurnsEvent(this.currentTurn));
}
+
+ override resetCards(playerId: number) {
+ var board: BoardPos[] | undefined = this.board.getSideByOwnerId(playerId);
+ if(typeof(board) != "undefined") {
+ board.map((pos: BoardPos) => {pos.creature.setIsReady(true);});
+ }
+ }
+
/**
* summons a creature to the side of player id at position number
*/
@@ -479,7 +515,6 @@ export class Game extends AbstractGame {
* @param boardPosition
* @param handPosition
*/
-
summonCardFromHand(playerId: number, boardPosition: number, handPosition: number){
let player = this.getPlayerById(playerId);
let card = player.hand[handPosition];
@@ -487,7 +522,9 @@ export class Game extends AbstractGame {
player.actions -= card.getCost();
player.hand.splice(handPosition, 1);
this.summonCard(playerId, boardPosition, card, player);
+ return card.name
}
+ return "";
}
/**
* function that lets me (front-end) do combat. pretty much, the turn players monster attacks and then we do different things based on if they control a monster or
@@ -519,11 +556,14 @@ export class Game extends AbstractGame {
}
c1.setIsReady(false);
}
-
}
- playCard(card: Card, playerId: number): boolean {
+
+ override playCard(card: Card, playerId: number): boolean {
if (this.turnPhase != TurnPhases.Play ||
- (Game.getInstance().getPlayerById(playerId) != null && Game.getInstance().getPlayerById(playerId).actions >= card.getCost())) {
+ (Game.getInstance().getPlayerById(playerId) == null && Game.getInstance().getPlayerById(playerId).actions >= card.getCost())) {
+ // console.log("Unable to play card " + card.name + "! Potential causes: this.turnPhase == TurnPhases.Play: " + (this.turnPhase == TurnPhases.Play) +
+ // ", Player from playerId == null: " + (Game.getInstance().getPlayerById(playerId) == null) +
+ // ", Player has enough actions: " + (Game.getInstance().getPlayerById(playerId).actions >= card.getCost()));
return false;
}
@@ -533,14 +573,16 @@ export class Game extends AbstractGame {
new GetBoardPosTargetEvent(
GetCardTargetEvent,
(pos: BoardPos) => {
- if (pos.creature != Creature.getNull()) {
+ if (!pos.creature.equals(Creature.getNull())) {
return false;
} else {
- if (card.play(pos, playerId)) {
+ if (card.play(pos, pos.ownerId)) {
+ Game.getInstance().getPlayerById(playerId).actions -= card.getCost();
+ Game.getInstance().getPlayerById(playerId).discardCard(card);
return Game.getInstance().dispatchEvent(
new PlayCardEvent(
card,
- playerId,
+ pos.ownerId,
),
);
}