Commit 0a7a16fa authored by evgen moruzhenko's avatar evgen moruzhenko

ref: game class, app config, minor changes.

parent 827fccb0
export const BOT_TOKEN = 'ODY5NTY4MDE5NjIwMjk4Nzky.YQAGUw.kW8iDvISPRXZmD60GjoVpRRALZg'
Please register or sign in to reply
export const BOT_COMMAND_PREFIX = '/';
import { Message } from 'discord.js';
enum places {
_Place = '\u2423',
xPlace = '\u2715',
oPlace = '0',
}
export class GameMessage {
static winningMessage = (player: string): string => `Player ${player} has won!`;
static drawMessage = (): string => `Game ended in a draw!`;
static currentPlayerTurn = (player: string): string => `It's ${player}'s turn`;
}
class Game {
private screen: Message;
private winningConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
private initialGameState: string[] = [
Please register or sign in to reply
places._Place, places._Place, places._Place,
places._Place, places._Place, places._Place,
places._Place, places._Place, places._Place
];
public gameActive = true;
public currentPlayer = places.xPlace;
public gameState: string[];
private handleResultValidation() {
let roundWon = false;
for (let i = 0; i < this.winningConditions.length; i++) {
const winCondition = this.winningConditions[i];
if (
this.gameState[winCondition[0]] === places._Place ||
this.gameState[winCondition[1]] === places._Place ||
this.gameState[winCondition[2]] === places._Place
) {
continue;
}
if (
this.gameState[winCondition[0]] === this.gameState[winCondition[1]] &&
this.gameState[winCondition[1]] === this.gameState[winCondition[2]]
) {
roundWon = true;
break
}
}
if (roundWon) {
this.screen.channel.send(GameMessage.winningMessage(this.currentPlayer));
this.gameActive = false;
return;
}
let roundDraw = !this.gameState.includes(places._Place);
if (roundDraw) {
this.screen.channel.send(GameMessage.drawMessage());
this.gameActive = false;
return;
}
this.handlePlayerChange();
}
private handlePlayerChange() {
this.currentPlayer = this.currentPlayer === places.xPlace ? places.oPlace : places.xPlace;
this.screen.channel.send(GameMessage.currentPlayerTurn(this.currentPlayer));
if (this.currentPlayer === places.oPlace) this.doAction();
}
private handleCellPlayed(cellIndex: number) {
this.gameState[cellIndex] = this.currentPlayer;
}
private doAction() {
let place: number;
do {
place = Math.floor(Math.random() * (9 - 1) + 1);
} while (this.gameState[place - 1] !== places._Place);
this.handleCellSelected(place);
}
public handleRestartGame() {
this.gameActive = true;
this.currentPlayer = places.xPlace;
this.gameState = [...this.initialGameState];
this.screen.channel.send(GameMessage.currentPlayerTurn(this.currentPlayer));
}
public handleCellSelected(cellNumber: number) {
const cellIndex = cellNumber - 1;
if (this.gameState[cellIndex] !== places._Place || !this.gameActive) {
this.screen.reply('No-no-no! This place is placed!');
return;
}
this.handleCellPlayed(cellIndex);
this.handleResultValidation();
}
public prepareStateArrayToOutput(): string {
const field = [];
for (let i = 0; i < this.gameState.length; i += 1) {
if (i == 2 || i == 5 || i == 8) {
field.push(this.gameState.slice(i - 2, i + 1).join('|'));
}
}
return field.join('\n');
}
public setScreen(screen: Message) {
this.screen = screen;
}
}
export default new Game();
......@@ -2,124 +2,11 @@ import { Injectable, Logger } from '@nestjs/common';
import { Once, ClientProvider, Client, OnCommand } from 'discord-nestjs';
import { Message, MessageEmbed } from 'discord.js';
import game, { GameMessage } from './bot.game';
@Injectable()
export class BotGateway {
private readonly logger = new Logger(BotGateway.name);
private screen: Message;
private _Place = '\u2423';
private xPlace = '\u2715';
private oPlace = '\u006F';
private gameActive = true;
private currentPlayer = this.xPlace;
private gameState = [
this._Place, this._Place, this._Place,
this._Place, this._Place, this._Place,
this._Place, this._Place, this._Place
];
private winningMessage = () => `Player ${this.currentPlayer} has won!`;
private drawMessage = () => `Game ended in a draw!`;
private currentPlayerTurn = () => `It's ${this.currentPlayer}'s turn`;
private winningConditions = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
private gameStateToField(stateArray: string[]) {
const field = [];
for (let i = 0; i < stateArray.length; i += 1) {
if (i == 2 || i == 5 || i == 8) {
const temp = [];
temp.push(stateArray[i - 2]);
temp.push(stateArray[i - 1]);
temp.push(stateArray[i]);
field.push(temp);
}
}
return field;
}
private handleResultValidation() {
let roundWon = false;
for (let i = 0; i <= 7; i++) {
const winCondition = this.winningConditions[i];
let a = this.gameState[winCondition[0]];
let b = this.gameState[winCondition[1]];
let c = this.gameState[winCondition[2]];
if (a === this._Place || b === this._Place || c === this._Place) {
continue;
}
if (a === b && b === c) {
roundWon = true;
break
}
}
if (roundWon) {
this.screen.channel.send(this.winningMessage());
this.gameActive = false;
return;
}
let roundDraw = !this.gameState.includes(this._Place);
if (roundDraw) {
this.screen.channel.send(this.drawMessage());
this.gameActive = false;
return;
}
this.handlePlayerChange();
}
private handlePlayerChange() {
this.currentPlayer = this.currentPlayer === this.xPlace ? this.oPlace : this.xPlace;
this.screen.channel.send(this.currentPlayerTurn());
if (this.currentPlayer === this.oPlace) this.doAction();
}
private handleRestartGame() {
this.gameActive = true;
this.currentPlayer = this.xPlace;
this.gameState = [
this._Place, this._Place, this._Place,
this._Place, this._Place, this._Place,
this._Place, this._Place, this._Place
];
this.screen.channel.send(this.currentPlayerTurn());
}
private handleCellPlayed(cellIndex: number) {
this.gameState[cellIndex] = this.currentPlayer;
}
private handleCellSelected(cellNumber: number) {
const cellIndex = cellNumber - 1;
if (this.gameState[cellIndex] !== this._Place || !this.gameActive) {
this.screen.reply('No-no-no! This place is placed!');
return;
}
this.handleCellPlayed(cellIndex);
this.handleResultValidation();
}
private doAction() {
let place = Math.floor(Math.random() * (9 - 1) + 1);
while (this.gameState[place - 1] !== this._Place) {
place = Math.floor(Math.random() * (9 - 1) + 1);
}
this.handleCellSelected(place);
}
@Client()
discordProvider: ClientProvider;
......@@ -128,28 +15,27 @@ export class BotGateway {
onReady(): void {
this.logger.log(`Logged in as ${this.discordProvider.getClient().user!.tag}!`);
}
@OnCommand({ name: 'start' })
async onStart(message: Message): Promise<void> {
this.screen = message;
this.handleRestartGame();
game.setScreen(message);
game.handleRestartGame();
const reply = new MessageEmbed().addFields({
name: this.currentPlayerTurn(),
value: this.gameStateToField(this.gameState) },
name: GameMessage.currentPlayerTurn(game.currentPlayer),
value: game.prepareStateArrayToOutput() },
);
await message.channel.send(reply);
}
@OnCommand({ name: 'place' })
async onPlace(message: Message): Promise<void> {
@OnCommand({ name: 'set' })
async onCommandSet(message: Message): Promise<void> {
const position: number = Number(message.toString().split(' ')[1]);
this.screen = message;
this.handleCellSelected(position);
game.setScreen(message);
game.handleCellSelected(position);
const reply = new MessageEmbed().addFields({
name: this.currentPlayerTurn(),
value: this.gameStateToField(this.gameState) },
name: GameMessage.currentPlayerTurn(game.currentPlayer),
value: game.prepareStateArrayToOutput() },
);
await message.channel.send(reply);
}
......
......@@ -2,11 +2,13 @@ import { Module } from '@nestjs/common';
import { DiscordModule } from 'discord-nestjs';
import { BotGateway } from './bot.gateway';
import { BOT_TOKEN, BOT_COMMAND_PREFIX} from '../app.config';
@Module({
imports: [
DiscordModule.forRoot({
token: 'ODY5NTY4MDE5NjIwMjk4Nzky.YQAGUw.kW8iDvISPRXZmD60GjoVpRRALZg',
commandPrefix: '/',
token: BOT_TOKEN,
commandPrefix: BOT_COMMAND_PREFIX,
}),
],
providers: [BotGateway],
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment