Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to gameplay logic #58

Open
wants to merge 7 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"next:check-types": "yarn workspace @se-2/nextjs check-types",
"next:build": "yarn workspace @se-2/nextjs build",
"next:serve": "yarn workspace @se-2/nextjs serve",
"next:cron": "yarn workspace @se-2/nextjs cron",
"postinstall": "husky install",
"precommit": "lint-staged",
"vercel": "yarn workspace @se-2/nextjs vercel",
Expand Down
60 changes: 19 additions & 41 deletions packages/nextjs/app/api/game/updategameround/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,25 @@ export const PATCH = async (request: Request) => {
const body = await request.json();
const { id, newRound } = body;
await connectdb();
const game = await Game.findById(id);

if (!game) {
return new NextResponse(JSON.stringify({ error: "Game not found" }), { status: 403 });
}

if (game.status === "finished" || game.currentRound > game.totalRounds - 1) {
const errorMessage = game.status === "finished" ? "Game has finished" : "Game is on the last round";
return new NextResponse(JSON.stringify({ error: errorMessage }), { status: 403 });
}
const game = await Game.findOneAndUpdate(
{ _id: id, status: { $ne: "finished" }, currentRound: { $lt: newRound } },
{ $set: { currentRound: newRound, lastRoundStartTimestamp: Date.now() } },
{ new: true },
);

if (newRound == game.currentRound) {
if (!game) {
return new NextResponse(
JSON.stringify({
game: game,
error: "Game not found or invalid round update",
}),
{
status: 200,
},
{ status: 403 },
);
}

const isFinalRound = newRound === game.totalRounds;

// Update players only if the round has changed
for (const player of game.players) {
const currentPlayerRound = player.currentRound;
if (currentPlayerRound < newRound) {
Expand All @@ -40,11 +35,7 @@ export const PATCH = async (request: Request) => {

let roundEntry = player.rounds.find((r: any) => r.round === currentPlayerRound);
if (!roundEntry) {
roundEntry = {
round: currentPlayerRound,
points: 0,
won: false,
};
roundEntry = { round: currentPlayerRound, points: 0, won: false };
player.rounds.push(roundEntry);
} else if (!isFinalRound) {
player.rounds[currentPlayerRound].points = 0;
Expand All @@ -53,36 +44,23 @@ export const PATCH = async (request: Request) => {
}
}

let message = `Moving to round ${newRound + 1}`;
if (newRound === game.totalRounds) {
game.status = "finished";
message = "Ended game successfully";
}
if (isFinalRound) game.status = "finished";

if (newRound !== game.totalRounds) game.currentRound = newRound;
game.lastRoundStartTimestamp = Date.now();
await game.save(); // Save the updated game state

const updatedGame = await game.save();
const gameChannel = ablyRealtime.channels.get("gameUpdate");
await gameChannel.publish("gameUpdate", updatedGame);
await gameChannel.publish("gameUpdate", game);

return new NextResponse(
JSON.stringify({
message: message,
game: updatedGame,
message: isFinalRound ? "Ended game successfully" : `Moving to round ${newRound + 1}`,
game,
}),
{
status: 200,
},
{ status: 200 },
);
} catch (error) {
return new NextResponse(
JSON.stringify({
error: "Error updating Game Round " + (error as Error).message,
}),
{
status: 500,
},
);
return new NextResponse(JSON.stringify({ error: "Error updating Game Round: " + (error as Error).message }), {
status: 500,
});
}
};
80 changes: 35 additions & 45 deletions packages/nextjs/app/api/player/updateplayerround/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,92 +12,82 @@ export const PATCH = async (request: Request) => {
await connectdb();
const game = await Game.findById(id);
if (!game) {
return new NextResponse(JSON.stringify({ error: "Game not found" }), { status: 403 });
return NextResponse.json({ error: "Game not found" }, { status: 403 });
}

const player = game.players.find((p: Player) => p.address === address);
if (!player) {
return new NextResponse(JSON.stringify({ error: "Player not found" }), { status: 403 });
return NextResponse.json({ error: "Player not found" }, { status: 403 });
}

if (game.status === "finished") {
return new NextResponse(JSON.stringify({ error: "Game has finished" }), { status: 403 });
return NextResponse.json({ error: "Game has finished" }, { status: 403 });
}

if (player.currentRound > game.totalRounds - 1) {
return new NextResponse(JSON.stringify({ error: "You have passed the last round" }), { status: 403 });
return NextResponse.json({ error: "You have passed the last round" }, { status: 403 });
}

if (player.currentRound > game.currentRound) {
return new NextResponse(JSON.stringify({ error: "You are ahead of the current game round" }), { status: 403 });
return NextResponse.json({ error: "You are ahead of the current game round" }, { status: 403 });
}

const anyPlayerAhead = game.players.some((p: Player) => p.currentRound > game.currentRound);
const currentPlayerRound = player.currentRound;
const isFinalRound = player.currentRound === game.totalRounds - 1;
const isCurrentRound = currentPlayerRound === game.currentRound;
const finalRound = game.totalRounds - 1;
const anyPlayerHasWonFinalRound = game.players.some((p: Player) => {
const finalRoundEntry = p.rounds.find((r: any) => r.round === finalRound);
return finalRoundEntry && finalRoundEntry.won;
});

// Find or create the current round entry
if (!game.winners[currentPlayerRound]) {
game.winners[currentPlayerRound] = [];
}

const isAlreadyWinner = game.winners[currentPlayerRound].includes(address);
if (won && !isAlreadyWinner) {
game.winners[currentPlayerRound].push(address);
}

let roundEntry = player.rounds.find((r: any) => r.round === currentPlayerRound);
if (!roundEntry) {
roundEntry = {
round: currentPlayerRound,
points: 0,
won: false,
};
roundEntry = { round: currentPlayerRound, points: 0, won: false };
player.rounds.push(roundEntry);
}

player.rounds[currentPlayerRound].points = won ? (!game?.winners[currentPlayerRound] ? 3 : 1) : 0;
player.rounds[currentPlayerRound].won = won;

if (!game.winners[currentPlayerRound]) {
game.winners[currentPlayerRound] = [];
if (won && !isAlreadyWinner) {
roundEntry.points = game.winners[currentPlayerRound].length === 1 ? 3 : 1;
} else {
roundEntry.points = 0;
}
game.winners[currentPlayerRound].push(address);
roundEntry.won = won;

if ((isCurrentRound && !anyPlayerAhead) || (isFinalRound && !anyPlayerHasWonFinalRound)) {
const anyPlayerAhead = game.players.some((p: Player) => p.currentRound > game.currentRound);
if (!anyPlayerAhead) {
const roundChannel = ablyRealtime.channels.get("updateRound");
const nextRoundTimestamp = Date.now() + 20000;
game.nextRoundTimestamp = nextRoundTimestamp;
await game.save();
await roundChannel.publish("updateRound", game);
} else {
await game.save();
}

if (isFinalRound) {
if (currentPlayerRound === game.totalRounds - 1) {
player.status = "waiting";
} else {
player.currentRound += 1;
player.status = "waiting";
}

const updatedGame = await game.save();

const gameChannel = ablyRealtime.channels.get("gameUpdate");
const playerChannel = ablyRealtime.channels.get("playerUpdate");
if (!anyPlayerAhead) await gameChannel.publish("gameUpdate", updatedGame);
if (!anyPlayerAhead) await gameChannel.publish("gameUpdate", game);
await playerChannel.publish("playerUpdate", player);

return new NextResponse(
JSON.stringify({
message: `Updated current player round to ${player.currentRound}`,
game: updatedGame,
player: player,
}),
return NextResponse.json(
{
status: 200,
message: `Updated current player round to ${player.currentRound}`,
game,
player,
},
{ status: 200 },
);
} catch (error) {
return new NextResponse(
JSON.stringify({
error: "Error updating player round " + (error as Error).message,
}),
{
status: 500,
},
);
return NextResponse.json({ error: "Error updating player round: " + (error as Error).message }, { status: 500 });
}
};
Loading