Need help with Tic Tac Toe block function


#1

Im having an issue with creating a block function in Tic Tac Toe. What Im trying to do here is make a function that will tell the computer there is a play on the board that need to be blocked to avoid a user win.

I have an array of arrays of all the possible win combinations, that is winCombo. I also have an array of all the user moves made so far in userMove. What I would like to do is create a block function that will compare the user moves against the winning combo, and if two moves match, the result will be the specific array of the winning combo, of which the computer will select the final play in that array to block the users win.

After a day and a half on this one thing, I finally got it to the point where it will find any winning combo that contains the last users move, but I need it to find the winning combo that includes at least 2 values in userMove… and totally stuck with how to do that. Heres what I have for my block function…help please! Thank you!

function block() {
        //iterate through array of winning combos
        for (i = 0; i < winCombo.length; i++) {
            //iterate through array of user moves so far
            for (j = 0; j < userMove.length; j++) {

                //check if user move matches values in winning combo array
                if (inArr(userMove[j], winCombo[i])) {
                    console.log("They're about to win here!");
                    console.log(userMove[j] + "win" + winCombo[i]);
                }
            }
            
        }
    }

#2

I have some ideas and some questions.

Does userMove include all game moves or just the user’s? Are the computer moves in a different place?

When I built it, I maintained a single array that looked sort of like this: ['x','x','o','-','-','x',...]. I think this would make it easier to compare the game array with winCombo (if winCombo is arrays of full games too), but your winCombo array might not support that.

Without seeing how you’re storing state/gameData, it’s tough to recommend anything else. I don’t see anything wrong with your logic (I might’ve tried .forEach() first, but both methods get the same result). Something like lodash might help with array comparisons too.

Hope that helps. I’ll try to help more if I can. :slight_smile:


#3

I second that - your strategy depends on a lot of things - the representation of moves in winCombo and userMove - the check in inArr - when the check is done i.e. the context of block

often the reason one gets stuck is you’ve bitten off too much - break it down - then break it down even more - find the smallest problem you can firmly grasp - solve and confirm your solution - it requires a lot of patience - the benefit is you’ll never be so deep in a hole of code you can’t climb out of


#4

Here is a little repel i did … trying to use your code and have also added a checking function thats part of a function i use in my tic tac toe game for blocking moves

with regards to yours could you post the inArr(userMove[j], winCombo[i]) function used here as i need to know whats going on there.
added debugger statement in my repel so if you also open dev tools and hit run on repl i will stop so you can step through code to see whats going on
forgot to add i return this win and then filter it to pull out the number i require eg in below it gives me 3,5,7 i then filter out number 7 as one needed to block with


#5

Thank you so so much everyone! I already feel better knowing im not completely in left field and completely wrong, cause thats how I was starting to feel. But you’re all totally on track with what Im trying to do. :slight_smile:

@DaveC userMove has the user moves, and I have another array aiMove to track the computers moves. My thought was, that way, depending on whose turn it is, either the user or computers move array would be compared against winning moves to see if a winning combo has been made and declare a winner / end the game.

@ppc Yeah trying to do this bit by bit… the project overall is ambitious I have to admit, cause Im doing more than the challenge calls for :laughing: but right now just trying to get the actual gameplay working, and this block thing is kicking my butt …tears!

@JohnL3 You have it exactly right…that is exactly how my userMove and winCombo arrays are set up…only difference is instead of numbers, I used descriptive text for the move positions. Im going ot study your repl.it to understand what you did here.

I went ahead and uploaded what I have so far…http://candicedavidson.com/portfolio/tictactoe

…and heres a direct link to the full js script http://candicedavidson.com/portfolio/tictactoe/script.js

ETA - I have a lot of work to do still on the layout /responsiveness…just focused on the gameplay right now. Also, I thought Id mention, I dont have all the winning combos in the winCombo array yet… just trying to test with those particular winning moves before I move on to all of them.


#6

Okay awesome… I think Ive got it what you did here! The only line Im kind of confused about this one… why -1 ?

if(hands[y-1].includes(moves[z-1]))


#7

ok you see at top winCombo … this is all the winning hand combinations eg 1,2,3 would be the top line of tic tac toe board 1,5,9 would be a diagonal line
my function is made function checkingHands(hands, moves,type) looking for 3 paramaters
and called like checkingHands(winCombo,userMove,‘p2’) so winCombo becomes hands, userMove is moves and type is ‘p2’ … should have used 'p1’
as its the comp p2 thats checking player moves
so in the line if(hands[y-1].includes(moves[z-1])) … if winCombo [y-1] eg [3,5,7] includes moves[z-1] eg 5
i increase count by 1 then check if count is == 2 then i check winCombo [y-1] [3,5,7] by moves[z-1] eg 9 rember its for loop so z increases each loop (and i am also checking from last to first in both arrays) and then check [3,5,7] for 3 and if count equals 2 i have a win and in this case i do as 3,5,7 contains 3,5
so i return win which will be [3,5,7] … in another function i then filter this against my moves to find the move i need eg 7 … pick this and block complete


#8

Here is a print out of my console log to show my function calls and how game plays out … you can see the playermoves eg Human is simple enough and stays the same … but the comp moves are more complicated and can change depending on plays made by Human … this was a tough assignment but great for working on your logic which i feel is more important and overlooked … as the code used in my case is nothing special

compMove
CompStarted
compStartedFirstMove
in removeChoice 9
in removeWinHands
9
In render

in playerMove 0
in removeChoice 6
in removeWinHands
6
In render

compMove
CompStarted
compStartedFirstMove
in removeChoice 3
in removeWinHands
3
In render

in playerMove 1
in removeChoice 2
in removeWinHands
2
In render

compMove
CompStarted
Checking to see if comp has winning play
in compCheckForWinHand …
NO WINNER
in compCheckForWinHand …
NO WINNER
Now LETS GO PICK A NUMBER
compStartedPickNumber
DOUBLECHANCE
[ 9, 3, 6, 2 ]
[ 1, 7 ]
in removeChoice 7
in removeWinHands
7
In render

in playerMove 2
in removeChoice 5
in removeWinHands
5
In render

compMove
CompStarted
Checking to see if comp has winning play
in compCheckForWinHand …
WIN 7,8,9
I HAVE A WINNER …7,8,9
sending to winner
in removeChoice 8
in removeWinHands
8
In render


#9

Oh my gosh I actually understood that! Thank you! And also explains why it selected [3,5,7] instead of [1,2,3] which was something else I was curious about.

Thank you so much!!!


#10

Yes you are right…this really is the most challenging assignment yet… I noticed some have used the minimax algo for the computers moves,and I considered it, but I simply could not wrap my head around what each line does, and I dont want to use anything I dont understand. After 2 days of trying to dissect Minimax, I decided I may as well spend all that time building the logic myself.

Its going to feel so good when Im done with this project, that is for sure lol


#11

I won’t press - just few things to think about when you’re done with the current approach or want to take a step back to reconsider

  1. what is the most natural and simplest representation of a tic tac toe board
  2. Say you figure out how to play the game - not to win - just know for your representation whether game is over or can continue - can you reuse what you have for gameplay as a blocking strategy
  3. if you draw a tic tac toe board on paper in any state how quickly can you tell how to block the opponent - i.e. what’s the minimal info you need for a blocking move
  4. if blocking is not required what is the best move at any time toward a win - what is the minimal info needed for such a move

#12

Also while my game works and i cant beat it … its rough and ready … i have to go back and redo game to make it look nice and will look at code to see if i can improve on it . i just wanted to see if i could create an unbeatable game of tic tac toe but its not my focus at the moment or then as im focusing on backend … but i do really enjoy trying to crack the logic behind doing things like this so i worked away at it till i got the logic done and then left it lol lol


#13

Oh press away… having more to think about def helps

  1. Not to sure what you mean? If its how I labeled my board, I know most people use numbers, but for me it was more intuitive to describe the move locations ie TOP, MID, CTL (corner top left) etc… That way when Im working out my strategy for the first 2 moves, I can easily see what Im looking at.

  2. The block / win strategy is kind of the crux of my gameplay algo…the first 2 moves set up the gameplay to hopfully get the user in a corner, then for every move after, the ai first looks to see if it needs to block the user, and then looks to see if it can play a winning move. So the idea is, once I have the block set up, it will be reused before every move.

  3. Yup, this is where my winCombo comes in, as long as the userMove matches at least 2 in one array of the winCombo, then the computer needs to block by making a move in the remaining space of that array.

  4. This goes back to the block / win strategy. The win strategy is set up in the first 2 moves, so from the get go, the computer already has a plan, so to speak…if theres nothing to block, play to win. :smiley:


#14

I totally understand… thats how I usually work these projects actually, Ill first work out the logic and get the back end functioning, since thats the part I like the most, then when Im done with that, then Ill try to make things look good.

But…I was so stressing over how to tackle this and started out so overwhelmed, that I worked on the design first to avoid getting to the backend lol I do try to do like ppc always says, to break things down into more managable parts and only concentrate on one step at a time, but for some reason, my brain just said nope, and refused to see anything other than the big picture. Once I started to break it down though, then it started to make sense what I need to concentrate on… Mostly, I just needed to get out of my head and have a lil faith in myself.


#15

ok - pressing on then

  1. I don’t actually see an abstract data representation of a board - there’s stuff about winning and blocking - but the basic board is missing - maybe it’s difficult to realize this when you start with a visual representation in HTML - but the game itself has nothing to do with HTML - the game should exist in your program independent of how its shown - forget about winning at this point - just come up with a simple and natural way of storing game data

#16

Hrmm…okay I see what you mean… but do I need to create a data representation of the board? Like my logic isnt really based on HTML… Im not looking at the board in a physical sense but with patterns…so if I say, TOP, MID, BOT is a winning sequence, thats the info it uses to determine its next move.

Like Im guessing you mean to create an array with the board layout as it physically is design wise and somehow refer to that instead of telling the computer what patterns to look for? That does change the entire concept of the path Im on, how does this logic work, as far as mapping out the board and determining which sequence is a win / block?

ETA: What you are saying does sound familiar as far as a lot of things i read while trying to understand the algo others have used… I just could not wrap my brain around it though lol and thats why I took to writing my own in a way that makes sense to me. But def am interested in the logic, cause it seems to be what everyone else but me understands! lol


#17

yes - data representation is the essence of all code - it drives the algorithms you can use or design - that determines how simple or complex your solution is - and how efficient or inefficient - and eventually how easy or hard it is to maintain the code and enhance it

in a sense when you draw the board on paper or see a board on paper your brain maps out a data representation for you based on your abstract reasoning abilities, right? That mental representation is what makes it easy or hard for a person to reason about a problem


#18

Definitely, that I get but thats in a broader sense… What I meant is specifically when you said you dont see a data representation of the board… The particular logic I used is to use data representation of the winning moves and do my logic checks against that. So I was curious about what you meant by representing the board layout instead.


#19

I agree you have a representation of winning - not of the bare board - if I’ve missed it could you tell me the object or variable name of the board?


#20

Oh def… here it is:

var allMoves = ["CTL", "TOP", "CTR", "LFT", "MID", "RGT", "CBL", "BOT", "CBR"];

Its all the moves in the board, and just happens to be in the order of the board top to bottom, left to right… but mostly I have that in there to check against to see if a space has already been played. I havnt gotten to writing that part of my code yet though.