Search code examples
javascriptnode.jsclassdiscord.jstic-tac-toe

Tic tac toe game in Discord (javascript) using classes, works first time around, then breaks in a weird way


I am quite new to javascript, and programming in general, and I am creating a Discord bot for my server for people to play games of tic tac toe against each other.

With my limited knowledge of how javascript works and how this game is supposed to work inside of Discord, I decided to use classes as a template for each game. To keep a text channel from being spammed by new messages after every move, I decided to create a class instance for each instance of a tic tac toe game is started, and to then keep editing one and the same message used as the playing field for one specific game. This also would allow for multiple games to be played at the same time without interfering with each other.

From within the 'main script', I manage the events that listen for incoming messages, and there it listens for a command to start a game of tic tac toe with an opponent.

Here I instantiate a game from the class in the tictactoe file:

client.on('message', async msg => {
    if(msg.author.bot || msg.channel.id != gamesChannel) return

    let args = msg.content.split(' ')
    let cmd = args[0].slice(prefix.length)

    switch(cmd){
        case 'ttt':
                let player = msg.author
                let opponent = GetUserFromMention(args[1])

                let tttGame = new tictactoe.Game(msg.channel, player, opponent)
                tttGame.Invite()
            }
        break
    }
})

From the invite() method on the tic tac toe Game class the game is 'managed' by going back and forth calling methods from inside the other methods on the class.

The way this game is played is the players can react to the message by pressing the reaction buttons of these markers (these markers each represent one of the 9 spots on the board) , that are initialised in an array like this inside the tic tac toe module: const markers = ['↖️', '⬆️', '↗️', '⬅️', '⏺️', '➡️', '↙️', '⬇️', '↘️']

This list is added as reactions to the post by the discord bot, and also is added to the class in the constructor: this.markers = markers

This is so that I can during the game remove markers from this array to indicate that this position on the board has already been occupied by one of the players' moves. (This is done by doing this.markers[i] = 'used' inside a method on the class)

Everything works fine on the first time a game is started, but the second time around it seems that somehow this constant array of the markers is altered, as when I do say 3 turns in a first game, then end that game and start a second game, and console log this array, it displays the array with the 'used' strings replacing the same markers that were used up in the first game, despite this array being a constant variable, and me only ever changing the array that is tied to the class. This has me very confused.

If someone is able to shed some light on what I'm doing wrong here that would be wonderful.

Thanks in advance!


Solution

  • In your constructor, use this.markers = markers.slice(); A const declaration doesn't make the array constant, just the variable binding. An assignment does not copy the array reference either, so you need to perform a shallow copy of the array in order to avoid mutating what the initial markers should be. – Patrick Roberts 25 mins ago

    Thanks a lot! Works perfectly now! :)