There is no unexpected result, except the flipping of more than 1 and the double tap error
The flipping of more that one chip is the “unexpected result” when only 1 chip should be flipped, chip 4,5.
Only chip 4,5 should get flipped when 4,6 is selected, but chip 5,5 is getting flipped also. This should NOT happen.
I’m assuming you have the print_r.lua working now. You will need to look at the CellTable and the CaptureTable results printed in the console.
There is a typo near the bottom of your UpRight vector code block.
print("***Up_Right vector / CellTable prints below")
print_r.print_r(CaptureTable)
Change to this so the print out of the CaptureTable in the console is not confusing.
print("***Up_Right vector / CaptureTable prints below")
print_r.print_r(CaptureTable)
When 4,6 is selected, the UpRight vector code is adding 4 cells to the CellTable. It’s adding ALL the cells along the UpRight vector to the CellTable, This is problem with the code we must fix.
\*\*\*Up\_Right vector / CellTable prints below table: 0x7fbc80553a60 { #[1] =\> table: 0x7fbc80553a60 { [row] =\> 5 [col] =\> 5 } #[2] =\> table: 0x7fbc80553a60 { [row] =\> 4 [col] =\> 6 } #[3] =\> table: 0x7fbc80553a60 { [row] =\> 3 [col] =\> 7 } #[4] =\> table: 0x7fbc80553a60 { [row] =\> 2 [col] =\> 8 } }
The good news is the code block is adding cells along the vector, but we have to limit the cells it’s capturing with Conditional statements in our loop.
the code needs to ONLY add chips along the vector that are colored and do not have a state == “blank”. If we find a cell that is “blank” or empty, we need to stop the vector code from adding these cells to the CellTable.
The code needs to STOP adding cells along the vector when a “blank” cell is found and not add that cell to the CellTable.
The loop will need to “break” when a “blank” cell is found with a conditional statement and stop adding invalid cells to the CellTable.
So in the UpRight vector we are using, how can we determine the .state of cell 5,5 and verify cell 5,5 is colored or “blank”, how can we determine the .state of cell 6,4 and verify cell 6,4 is colored or “blank”?
Since we spawned the cells of the game board into a table, and we know the cells coordinates are the same as the cells table value indexes, we can find the .state of any cell at anytime.
We need a conditional statement inside the loop to be met or not met before we add the cell along a vector to the CellTable.
something like this…
--this is for concept only if Cell.state == "blank" then --an empty cell has been found --when this condition is met, the loop will stop adding cells to the CellTable when we call break break else add the Cell on the vector to the CellTable end
Nail
should I write this way Sir?
for i = Row, 1 , -1 do tempCol = tempCol +1 tempRow = tempRow -1 --new cell validator --This is needed in ALL vector blocks if tempCol \> 8 or tempCol \< 1 or tempRow \> 8 or tempRow \< 1 or T[tempCol][tempRow].state=="blank".state=="blank" then --verify values are not out of range print("\*\*UpRight -- Cell out of Ranged") print("\*\*UpRight break") break --calling break will stop the loop when a condition is met, so no more cells will be added to the CellTable end \_index = #CellTable + 1 CellTable[\_index] = {} CellTable[\_index].col = tempCol CellTable[\_index].row = tempRow end
The location of the conditional statement will work, but there is a syntax error, it won’t run in the simulator because there is an error.
FWiW, you could put the conditional statement on it’s own, as long as it is located below the first cell validator chunk. Your location may be faster.
--new cell validator --This is needed in ALL vector blocks if tempCol \> 8 or tempCol \< 1 or tempRow \> 8 or tempRow \< 1 then --verify values are not out of range print("\*\*"..VT[k].vector.." -- Cell out of Ranged") print("\*\*"..VT[k].vector.." break") break --calling break will stop the loop when a condition is met, so no more cells will be added to the CellTable end if T[tempCol][tempRow].state == "blank" then --stop building CellTable if a "blank" cell is found break --stops the loop and goes to next vector block end
Did you try to run your code in the simulator? You should try to run your code and debug the problems on your own before you post.
--this is your line, -- or T[tempCol][tempRow].state=="blank".state=="blank" then --FYI, you can't compare 3 items in a conditional, only 2 -- =="blank".state== / this variable does not exist in the project, so you can't compare it to anything, it will kick en error --the conditional should read: or T[tempCol][tempRow].state=="blank" then --"blank", "black", "white" are our 3 possible values for the .state property of each cell
btw, all the vector code blocks will need this cell validator chunk, add it to your Up vector code block also. We never want to add “blank” cells to the CellTable.
Fix your code and run it. select the same 2 cells we have been using 5,6 then 4,6. are there unexpected results?
Nail
UPDATE: MODULE Released --> https://forums.coronalabs.com/topic/71820-reversi-aka-othello-module-complete/
I’ve been watching this thread with interest for a while. It inspired me to spend some time today making a Reversi module and a game supporting:
- Player Versus AI
- Player Versus Player
- AI Versus AI
The AI versus AI is running in this video and playing at the highest speed of one move per frame with 2 seconds between games.
I’m going to release the module and a full set of game examples tomorrow (Wed Feb 21 2018) on Sellfy. I’ll also post it to the Marketplace here.
https://forums.coronalabs.com/topic/71820-reversi-aka-othello-module-complete/
https://www.youtube.com/watch?v=I10Sjf2Wzzk&feature=youtu.be
https://www.youtube.com/watch?v=3o-IS3tH4HA&feature=youtu.be
for i = Row, 1 , -1 do tempCol = tempCol +1 tempRow = tempRow -1 --new cell validator --This is needed in ALL vector blocks if tempCol \> 8 or tempCol \< 1 or tempRow \> 8 or tempRow \< 1 then --verify values are not out of range print("\*\*UpRight -- Cell out of Ranged") print("\*\*UpRight break") print("\*\*"..VT[k].vector.." -- Cell out of Ranged") print("\*\*"..VT[k].vector.." break") break --calling break will stop the loop when a condition is met, so no more cells will be added to the CellTable end if T[tempCol][tempRow].state == "blank" then --stop building CellTable if a "blank" cell is found break --stops the loop and goes to next vector block end \_index = #CellTable + 1 CellTable[\_index] = {} CellTable[\_index].col = tempCol CellTable[\_index].row = tempRow end
#2 --Start Up_Right Vector iteration
23:10:37.251 col == 4
23:10:37.251 row == 6
23:10:37.251 Col == 5
23:10:37.251 Row == 5
23:10:37.251 T[Col][Row].state == black
23:10:37.251 ***Up_Right vector / CellTable prints below
23:10:37.251 table: 09C69390 {
23:10:37.251 #[1] => table: 09C69390 {
23:10:37.251 [row] => 5
23:10:37.251 [col] => 5
23:10:37.251 }
23:10:37.251 }
23:10:37.251 ***Up_Right vector / Capture Table prints below
23:10:37.251 table: 09C68EE0 {
23:10:37.251 #[1] => table: 09C68EE0 {
23:10:37.251 [row] => 5
23:10:37.251 [col] => 4
23:10:37.251 }
23:10:37.251 #[2] => table: 09C68EE0 {
23:10:37.251 [row] => 5
23:10:37.251 [col] => 5
23:10:37.251 }
23:10:37.251 }
23:10:37.251 #FlipTable == 2
23:10:37.251 *#FlipTable == 2
23:10:37.262 **clicked == 0
23:10:37.262 {x=4, y=6}
that line don’t appear on the console Sir
First, in the cell validator chunk I posted above, there are 2 print statements that need to be commented out or remove if you were to use the chunk. They would kick an error. I can see you did not use my code chunk above, which is good.
--new cell validator --This is needed in ALL vector blocks if tempCol \> 8 or tempCol \< 1 or tempRow \> 8 or tempRow \< 1 then --verify values are not out of range print("\*\*UpRight -- Cell out of Ranged") print("\*\*UpRight break") -- these 2 print statements should be removed or commented out, we do not have a VT table -- print("\*\*"..VT[k].vector.." -- Cell out of Ranged") -- print("\*\*"..VT[k].vector.." break") break --calling break will stop the loop when a condition is met, so no more cells will be added to the CellTable end
At the bottom of you post above, you state " That line don’t appear in the console Sir".
I have no idea what you are referring to, could you be more specific.
There is the problem in the code though, your console print out shows the chip 5,5 is being added to the CellTable which is then added to the CaptureTable, so it will be flipped. This flip should NOT happen because cell 6,4 is blank. A chip should only be flipped if it is bound on the far side by a chip on the vector with the same color as the color in play. This is how the game should work, correct?
So the code must verify, with a conditional statement, that the last cell/chjp on the vector is the players color/State before the cells are added to the CaptureTable.
There are a few different ways to accomplish this. Here’s one.
Look at your console print out below, I commented the cell 5,5 that should NOT be added to the CaptureTable to be flipped.
\*\*\*Up\_Right vector / CellTable prints below 23:10:37.251 table: 09C69390 { 23:10:37.251 #[1] =\> table: 09C69390 { 23:10:37.251 [row] =\> 5 23:10:37.251 [col] =\> 5 23:10:37.251 } 23:10:37.251 } 23:10:37.251 \*\*\*Up\_Right vector / Capture Table prints below 23:10:37.251 table: 09C68EE0 { 23:10:37.251 #[1] =\> table: 09C68EE0 { 23:10:37.251 [row] =\> 5 23:10:37.251 [col] =\> 4 23:10:37.251 } 23:10:37.251 #[2] =\> table: 09C68EE0 { --This cell/chip should NOT be flipped, so it should NOT be added to the CaptureTable 23:10:37.251 [row] =\> 5 23:10:37.251 [col] =\> 5 23:10:37.251 } 23:10:37.251 }
the code chunk that adds the cells in the CellTable to the CaptureTable must have a conditional statement preceding it that verifies there is a bounding chip with the players color/state at the end of the vector, which is the last indexed member of the vectors CellTable. If this condition is NOT met, then no cells along the vector are to be added to the CaptureTable.
So how do we find the last indexed member of the CellTable, which would be the bounding cell and verify it is the player’s color/State?
#CellTable will return size of the vector’s CellTable, which is also the index of the last table member. This cell, the bounding cell, must be the players color/State as a condition to be met for the code adding cells to the CaptureTable to continue. We cannot add cells to the CaptureTable that are not supposed to be flipped.
Let’s add a new variable, BoundingCell, that is a copy of the bounding cell or last indexed member of the CellTable so we can check the game board and verify it’s color/State is the same as the Player’s color/State
local BoundingCell = CellTable[#CellTable] -- this is a copy of the last indexed member of the CellTable, or the bounding cell. -- it holds the col and row of the bounding cell print("BoundingCell prints below") print\_r.print\_r(BoundingCell) --let's print out the table so you can see the col and row of the bounding cell
In case you’ve forgotten, the “State” variable in the code is always the current Player’s color. So if you add a print statement anywhere in the code, you can always get the current Player’s color or State.
print("State == ",State") --this will display the current Player's color
You need to verify in a conditional statement, the bounding cell on the game board table T[BoundingCell.col][BoundingCell.row].state == State is met before any cells from the CellTable are added to the CaptureTable. Remember, if a cell is added to the CaptureTable, it will be flipped with no further checks for it’s validity.
if "you fill in the conditional statement" then --if the conditional statement is met, then add cells to the CaptureTable for i = 1, #CellTable do --starting near cell in play, put all Cells above of opposite color into a CaptureTable if T[CellTable[i].col][CellTable[i].row].state ~= State and T[CellTable[i].col][CellTable[i].row].state ~= "blank" then \_index = #CaptureTable + 1 CaptureTable[\_index] = {} CaptureTable[\_index].col = Col CaptureTable[\_index].row = Row elseif T[CellTable[i].col][CellTable[i].row].state == State then --when a cell with the same color is found, stop adding cells to CaptureTable print("break--cell matches State color") break end end print("\*\*\*Up\_Right vector / CaptureTable prints below") print\_r.print\_r(CaptureTable) end
Nail
Hi @mojric8888, I think before anyone can really help you, we are going to need to know more about how you’re tracking your pieces. So showing us some code about how your managing your pieces would be helpful. Beyond that about all we can do is suggest you do an Internet search on “programming Othello”.
When posting code, please use code formatting (the blue <> button in the row with Bold, Italic etc. and paste your code into the popup window.
Rob
-- Your code here display.setStatusBar(display.HiddenStatusBar) screenLeft = display.screenOriginX screenWidth = display.contentWidth - screenLeft \* 2 screenRight = screenLeft + screenWidth screenTop = display.screenOriginY screenHeight = display.contentHeight - screenTop \* 2 screenBottom = screenTop + screenHeight display.contentWidth = screenWidth display.contentHeight = screenHeight screenTopSB = screenTop + display.topStatusBarContentHeight -- when status bar is showing screenHeightSB = display.contentHeight - screenTopSB screenBottomSB = screenTopSB + screenHeightSB -- display.tl = display.TopLeftReferencePoint display.tc = display.TopCenterReferencePoint display.tr = display.TopRightReferencePoint display.cl = display.CenterLeftReferencePoint display.c = display.CenterReferencePoint display.cr = display.CenterRightReferencePoint display.bl = display.BottomLeftReferencePoint display.bc = display.BottomCenterReferencePoint display.br = display.BottomRightReferencePoint function startGame( event) local background2= display.newImageRect("background1.jpg",360, 650) background2.x=display.contentCenterX background2.y=display.contentCenterY background2.alpha=0 local cbs2= display.newImageRect("cbs2.png",320, 150) cbs2.x=display.contentCenterX cbs2.y=display.contentCenterY-220 local board1= display.newImageRect("board1.png",320,320) board1.x=display.contentCenterX board1.y=display.contentCenterY board1.alpha=0 -- body transition.to(background2,{time=1000, alpha=1, x=centerX,y=200}) transition.to(board1,{time=1000, alpha=1, x=centerX,y=centerY}) grid() end function grid() clicked=0 clicked1=0 local chip function chipTapped(event) local button = event.target local button1=event.target clicked=clicked+1 if (button.state=="blank") then if (clicked==1) then button.state=0 endtxt = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt.x=display.contentCenterX endtxt.y=display.contentCenterY transition.to( endtxt, {time=1500,alpha=0}) button = display.newImage("black.png") button.x=event.target.x button.y=event.target.y button.width=event.target.width button.height=event.target.height clicked=1 chip="black" return blackpiece end if (clicked==2) then button.state=0 endtxt1 = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt1.x=display.contentCenterX endtxt1.y=display.contentCenterY transition.to( endtxt1, {time=1500,alpha=0}) button1 = display.newImage("white.png") button1.x=event.target.x button1.y=event.target.y button1.width=event.target.width button1.height=event.target.height clicked=clicked-2 chip="white" return whitepiece end else if (chip=="white") then clicked=0 end if (chip=="black") then clicked=1 end end end local chipWidth = 38 local chipHeight = 38 local colSpace =0 local rowSpace =0 local numCols = 8 local numRows = 8 local centerY=display.contentCenterY local centerX= display.contentCenterX local xPos = centerX- (numCols \* chipWidth + numCols \* colSpace) / 2 local yPos = centerY - (numRows \* chipHeight + numRows \* rowSpace) / 2 local chip1={} for col=1,numCols do for row=1, numRows do chip1= display.newImage("square.png") chip1.width = chipWidth -- for testing only chip1.height = chipHeight -- for testing only chip1.x = xPos + col \* (chipWidth + colSpace) - chipWidth/2 - colSpace chip1.y = yPos + row\* (chipHeight + rowSpace) - chipHeight/2 - rowSpace chip1.alpha=0.1 chip1.gridPos = {x=col, y=row} chip1.state="blank" chip1:addEventListener("tap",chipTapped) end end end startGame()
that’s my code Sir…
i can’t finish it…since i am new in this language and besides I’m just a student
thank you in advance
mojric,
Curious here, are you a high school student or college? If college, what year and what is your major?
Also curious, are the images posted screenshots from your app or grabbed from the web as examples of what you’d like to do?
It would help others if you changed your display.newImage to display.newRect so others can run your code as they don’t have your .pngs. You can change back later when your code works.
I would personally try spawning your game board squares (they will hold all the variables needed to track game play) into a table so you can iterate over the squares adjacent to the square that is being selected and having a disc placed to determine if there are any discs adjacent to be captured and flipped. It will also determine if the selected square is a legal play.
Hope this helps,
Nail
I’m a 4th year BSMathematics major in CIT…
my school dont teach us how to so we have to study by ourselves
those images that I attached is from my project… what I like to do is to capture the white chip from [5][4] and turn into black…but I can’t
I’m sorry for using display.newImage … I just copy and paste it here…
I’m just a newbie in this corona sdk…
thank you for the help in advance
mojric,
Thanks for the info.
I fully understand you want to “Capture” the white disc, I’m sure there are several ways to do it. You need a systematic plan, algorithm, to work on every square in the grid to determine if adjacent discs can be captured. Think of the possibilities. this is the “engine” of the game. The engine needs to iterate over all the squares which means every square needs to be identifiable. We put this information in a table and is why I suggest spawning the squares into a table, the same table you will iterate over to determine if the White disc can be captured or even exists for that matter.
I’m curious, where are you getting those black and white discs from shown in your posted images? How are they being spawned? I don’t see them being spawned in your posted code. How do they show up in the squares?
In order to get help, it would be best if you act on my suggestions , if you don’t want to take the time to re-write your code, then neither do I. Fair?
Change your images to rects and post the code again so I can help you spawn your objects into a table which will have many uses.
FWIW, there may be a method to “Capture” the white disc from your existing code, I just don’t see it.
Hope this helps,
Nail
-- Your code here display.setStatusBar(display.HiddenStatusBar) screenLeft = display.screenOriginX screenWidth = display.contentWidth - screenLeft \* 2 screenRight = screenLeft + screenWidth screenTop = display.screenOriginY screenHeight = display.contentHeight - screenTop \* 2 screenBottom = screenTop + screenHeight display.contentWidth = screenWidth display.contentHeight = screenHeight screenTopSB = screenTop + display.topStatusBarContentHeight -- when status bar is showing screenHeightSB = display.contentHeight - screenTopSB screenBottomSB = screenTopSB + screenHeightSB -- display.tl = display.TopLeftReferencePoint display.tc = display.TopCenterReferencePoint display.tr = display.TopRightReferencePoint display.cl = display.CenterLeftReferencePoint display.c = display.CenterReferencePoint display.cr = display.CenterRightReferencePoint display.bl = display.BottomLeftReferencePoint display.bc = display.BottomCenterReferencePoint display.br = display.BottomRightReferencePoint cy=display.contentCenterY cx=display.contentCenterX function startGame( event) local background2= display.newRect(cx,cy,360, 650) background2.alpha=0 background2:setFillColor( 0 ) local cbs2= display.newRect(cx, cy-220,320, 150) cbs2:setFillColor( 0.5 ) local board1= display.newRect(cx,cy,320,320) board1.alpha=0 board1:setFillColor( 0 ) -- body transition.to(background2,{time=1000, alpha=1, x=centerX,y=200}) transition.to(board1,{time=1000, alpha=1, x=centerX,y=centerY}) grid() end function grid() clicked=0 clicked1=0 local chip function chipTapped(event) local button = event.target local button1=event.target clicked=clicked+1 if (button.state=="blank") then if (clicked==1) then button.state=0 endtxt = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt.x=display.contentCenterX endtxt.y=display.contentCenterY transition.to( endtxt, {time=1500,alpha=0}) button = display.newCircle(cx,cy,5) button:setFillColor(0) button.x=event.target.x button.y=event.target.y button.width=event.target.width button.height=event.target.height clicked=1 chip="black" return blackpiece end if (clicked==2) then button.state=0 endtxt1 = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt1.x=display.contentCenterX endtxt1.y=display.contentCenterY transition.to( endtxt1, {time=1500,alpha=0}) button1 = display.newCircle(cx,cy,5) button1:setFillColor(1) button1.x=event.target.x button1.y=event.target.y button1.width=event.target.width button1.height=event.target.height clicked=clicked-2 chip="white" return whitepiece end else if (chip=="white") then clicked=0 end if (chip=="black") then clicked=1 end end print("{x=" ..event.target.gridPos.x .. ", y=" .. event.target.gridPos.y .. "}") text = display.newText( "{x=" ..event.target.gridPos.x .. ", y=" .. event.target.gridPos.y .. "}", 0, 0, "Helvetica", 24 ) text.x = display.contentCenterX-60 text.y = display.contentCenterY-60 text.alpha=1 text:setTextColor(255, 254, 185) transition.to(text,{time=1500, alpha=0}) end --======================================== -- grid code --======================================== local chipWidth = 38 local chipHeight = 38 local colSpace =0 local rowSpace =0 local numCols = 8 local numRows = 8 local centerY=display.contentCenterY local centerX= display.contentCenterX local xPos = centerX- (numCols \* chipWidth + numCols \* colSpace) / 2 local yPos = centerY - (numRows \* chipHeight + numRows \* rowSpace) / 2 local chip1={} for col=1,numCols do for row=1, numRows do chip1= display.newRect(0,0,chipWidth,chipHeight) chip1.x = xPos + col \* (chipWidth + colSpace) - chipWidth/2 - colSpace chip1.y = yPos + row\* (chipHeight + rowSpace) - chipHeight/2 - rowSpace chip1.alpha=0.1 chip1.gridPos = {x=col, y=row} chip1.state="blank" chip1:addEventListener("tap",chipTapped) end end end startGame()
I’m sorry…but I really don’t know how to do what you had say
I just Change it to newRect
once the board is click, the chip appeared.
I just manipulate the chips to look like that, please help and teach me how to put the starting chips in the board and how to capture,
I saw a lua program that runs othello, but that’s just for console, I don’t know how to do it in sdk
take a look at this code, I cleaned up a few things, added variables to each square,you can remove the commented lines as I don’t think they are needed.
You can see each square now has a table indexed value corresponding to it’s game board location T[1][1] - top left squar, T[8][8] - bottom right square.
Now you can reference the center 4 squares to spawn them to begin the game and set their fill colors, states, row, col.
T[4][4]:setFillColor(1) --not sure what color it should be to start the game
--[[] --Comment these out as they aren't used and not needed' screenLeft = display.screenOriginX screenWidth = display.contentWidth - screenLeft \* 2 screenRight = screenLeft + screenWidth screenTop = display.screenOriginY screenHeight = display.contentHeight - screenTop \* 2 screenBottom = screenTop + screenHeight display.contentWidth = screenWidth display.contentHeight = screenHeight screenTopSB = screenTop + display.topStatusBarContentHeight -- when status bar is showing screenHeightSB = display.contentHeight - screenTopSB screenBottomSB = screenTopSB + screenHeightSB --]] -- --[[] display.tl = display.TopLeftReferencePoint display.tc = display.TopCenterReferencePoint display.tr = display.TopRightReferencePoint display.cl = display.CenterLeftReferencePoint display.c = display.CenterReferencePoint display.cr = display.CenterRightReferencePoint display.bl = display.BottomLeftReferencePoint display.bc = display.BottomCenterReferencePoint display.br = display.BottomRightReferencePoint --]] local DisplayGroup = display.newGroup() --declare display group to hold display objects local T = {} --replace Chips1 table below with a Table labeled "T" local text = {} --[[local text = display.newText( "Void", 0, 0, "Helvetica", 24 ) text.x = display.contentCenterX-60 text.y = display.contentCenterY-60 text.alpha=1 text:setTextColor(255, 254, 185) transition.to(text,{time=1500, alpha=0}) --]] cy=display.contentCenterY cx=display.contentCenterX function startGame( event) --remove all display objects and respawn the game board, this is an easy way to restart the game display.remove(DisplayGroup) DisplayGroup = nil DisplayGroup = display.newGroup() local background2= display.newRect(cx,cy,360, 650) background2.alpha=0 background2:setFillColor( 0 ) DisplayGroup:insert(background2) local cbs2= display.newRect(cx, cy-220,320, 150) cbs2:setFillColor( 0.5 ) local board1= display.newRect(cx,cy,320,320) board1.alpha=0 board1:setFillColor( 0 ) DisplayGroup:insert(cbs2) -- body transition.to(background2,{time=1000, alpha=1, x=centerX,y=200}) -- transition.to(board1,{time=1000, alpha=1, x=centerX,y=centerY}) grid() end function grid() local playCount = 0 local clicked=0 local clicked1=0 local chip function chipTapped(event) local button = event.target local button1=event.target local col = button.col local row = button.row playCount = playCount + 1 clicked=clicked+1 print("\*clicked == ",clicked) if (button.state=="blank") then if (clicked==1) then button.state=0 endtxt = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt.x=display.contentCenterX endtxt.y=display.contentCenterY transition.to( endtxt, {time=1500,alpha=0}) --[[] --spawn when table is created button = display.newCircle(cx,cy,5) button:setFillColor(0) button.x=event.target.x button.y=event.target.y button.width=event.target.width button.height=event.target.height --]] T[col][row].state=clicked --need to set state to player color, 1 = black T[col][row].originColor = "black" --need to set color T[col][row].originPlayCount = playCount T[col][row].Chip:setFillColor(0) T[col][row].Chip.isVisible = true clicked=1 chip="black" print("\*\*clicked == ",clicked) --return blackpiece end if (clicked==2) then --button.state=0 --set state below, this works fine, just setting variable in 1 area endtxt1 = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt1.x=display.contentCenterX endtxt1.y=display.contentCenterY transition.to( endtxt1, {time=1500,alpha=0}) --[[] --the discs are now spawned when the board is created in grid() button1 = display.newCircle(cx,cy,5) button1:setFillColor(1) button1.x=event.target.x button1.y=event.target.y button1.width=event.target.width button1.height=event.target.height --]] T[col][row].state=clicked --need to set state to player color, 2 = white T[col][row].originColor = "white" T[col][row].originPlayCount = playCount T[col][row].Chip:setFillColor(1) T[col][row].Chip.isVisible = true clicked=clicked-2 print("\*\*clicked == ",clicked) chip="white" --return whitepiece end else if (chip=="white") then clicked=0 end if (chip=="black") then clicked=1 end end print("{x=" ..event.target.gridPos.x .. ", y=" .. event.target.gridPos.y .. "}") text.alpha = 1 -- text.text = "{x=" ..event.target.gridPos.x .. ", y=" .. event.target.gridPos.y .. "}" text.text = "col= "..col.." / row= "..row.."" --[[text = display.newText( "{x=" ..event.target.gridPos.x .. ", y=" .. event.target.gridPos.y .. "}", 0, 0, "Helvetica", 24 ) text.x = display.contentCenterX-60 text.y = display.contentCenterY-60 text.alpha=1 text:setTextColor(255, 254, 185) --]] transition.to(text,{time=1500, alpha=0}) end --======================================== -- grid code --======================================== local chipWidth = 38 local chipHeight = 38 local colSpace =0 local rowSpace =0 local numCols = 8 local numRows = 8 local centerY=display.contentCenterY local centerX= display.contentCenterX local xPos = centerX- (numCols \* chipWidth + numCols \* colSpace) / 2 local yPos = centerY - (numRows \* chipHeight + numRows \* rowSpace) / 2 --clear table and respawn, display objects have already been removed in "startGame" when the DisplayGroup was cleared/removed T = nil T = {} for col=1,numCols do T[col] = {} --creates an indexed table for each col for row=1, numRows do T[col][row] = {} --creates an indexed table for each row in each col, look familiar? --T[1][1] will be the upper left square, T[8][8] will be the lower right square T[col][row]= display.newRect(0,0,chipWidth,chipHeight) T[col][row].x = xPos + col \* (chipWidth + colSpace) - chipWidth/2 - colSpace T[col][row].y = yPos + row\* (chipHeight + rowSpace) - chipHeight/2 - rowSpace T[col][row]:setFillColor(0.3, 0.6, 0.8) T[col][row].alpha=0.5 T[col][row].gridPos = {x=col, y=row} -- I'm going to seperate the gridPos references, it may be easier, not sure yet' T[col][row].col = col T[col][row].row = row T[col][row].state="blank" T[col][row].originColor = "Void" --will store the player color when first played T[col][row].originPlayCount = "Void" --will store the index when first played T[col][row]:addEventListener("tap",chipTapped) DisplayGroup:insert(T[col][row]) --add object to the display group T[col][row].Chip = display.newCircle(cx,cy,15) T[col][row].Chip:setFillColor(1) T[col][row].Chip.x = T[col][row].x T[col][row].Chip.y = T[col][row].y --T[col][row].Chip.width=event.target.width --T[col][row].Chip.height=event.target.height T[col][row].Chip.isVisible = false -- hide the Chip until played DisplayGroup:insert(T[col][row].Chip) end end text = display.newText( "Void", 0, 0, "Helvetica", 24 ) text.x = display.contentCenterX-60 --text.y = display.contentCenterY-60 text.y = 60 text.alpha=1 text:setTextColor(255, 254, 185) DisplayGroup:insert(text) transition.to(text,{time=1500, alpha=0}) end
this should give you a start, you need to create a function that looks at each square “T[col][row]” adjacent to the square that is played to determine if the play is legal and if there are any Chips to flip. for instance, if you select the top left square on your first move, your function should NOT allow the Chip to be displayed.
Nail
function start() T[4][5].originColor="white" T[4][5].originPlayCount = playCount T[4][5].Chip:setFillColor(1) T[4][5].Chip.isVisible = true T[4][5].state=0 T[5][4].originColor="white" T[5][4].originPlayCount = playCount T[5][4].Chip:setFillColor(1) T[5][4].Chip.isVisible = true T[5][4].state=0 T[5][5].originColor="black" T[5][5].originPlayCount = playCount T[5][5].Chip:setFillColor(0) T[5][5].Chip.isVisible = true T[5][5].state=0 T[4][4].originColor="black" T[4][4].originPlayCount = playCount T[4][4].Chip:setFillColor(0) T[4][4].Chip.isVisible = true T[4][4].state=0 end
I add this for starting chips,
I dont know how to make algorithm for getting legal moves, sorry about that
function OB:get\_valid\_moves(player) local x, y, vx, vy, piece local moves = {} local cells = {} local opp = self:get\_opponent(player) if opp == nil then return moves end -- Check every cell of the board... for x=1, self.size\_x do for y=1, self.size\_y do -- ...and if the cell is empty... if self:get\_cell(x, y) == " " then -- ...then check each of it's neighbors... for \_, vector in self.\_vectors do piece = self:get\_neighbor(x, y, vector) -- ...and if the neighbor contains the -- opponents piece... if piece == opp then -- ...traverse that vector looking for our -- player's piece. If we find our player, -- then we note the original blank x,y cell -- in our moves table. cells = self:traverse(x, y, vector) for \_, c in cells do vx, vy, obj = unpack(c) if obj == player then table.insert(moves, {x, y}) break end end end end end end end
I found that algorithm, but I don’t know how to translate it
Whien you start the game and spawn the first 4 Chips, you have to set the “T[4][4].state=0” to the color which is now a string, either “white” or “black”. You also have to set the other 2 origin variables for each cell.or square.
T[4][4].originColor = “white”
T[4][4].originPlayCount = 0 – since the first 4 chips are established at game start, we will set the originPlayCount to 0 for all 4 start chips.
the originColor and originPlayCount variables will be used if you want to display a “transcript” of the game after it is completed.
I’ve placed the start(() at the bottom of the grid().
replace the grid() in your file with this modified grid() so we can continue with the same code.
function grid() local playCount = 0 local clicked=0 local clicked1=0 local chip function chipTapped(event) local button = event.target local button1=event.target local col = button.col local row = button.row playCount = playCount + 1 clicked=clicked+1 print("\*clicked == ",clicked) local State = "Void" --we will change the state to a string, "ehite" or "black" if clicked == 1 then State = "black" elseif clicked == 2 then State = "white" end if (button.state=="blank") then if (clicked==1) then button.state=0 endtxt = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt.x=display.contentCenterX endtxt.y=display.contentCenterY transition.to( endtxt, {time=1500,alpha=0}) T[col][row].state = State T[col][row].originColor = "black" --need to set color T[col][row].originPlayCount = playCount T[col][row].Chip:setFillColor(0) T[col][row].Chip.isVisible = true clicked=1 chip="black" print("\*\*clicked == ",clicked) --return blackpiece end if (clicked==2) then --button.state=0 --set state below, this works fine, just setting variable in 1 area endtxt1 = display.newText( clicked, 0, 0, native.systemFont, 24 ) endtxt1.x=display.contentCenterX endtxt1.y=display.contentCenterY transition.to( endtxt1, {time=1500,alpha=0}) T[col][row].state = State T[col][row].originColor = "white" T[col][row].originPlayCount = playCount T[col][row].Chip:setFillColor(1) T[col][row].Chip.isVisible = true clicked=clicked-2 print("\*\*clicked == ",clicked) chip="white" --return whitepiece end else if (chip=="white") then clicked=0 end if (chip=="black") then clicked=1 end end print("{x=" ..event.target.gridPos.x .. ", y=" .. event.target.gridPos.y .. "}") text.alpha = 1 -- text.text = "{x=" ..event.target.gridPos.x .. ", y=" .. event.target.gridPos.y .. "}" text.text = "State= "..State.." / col= "..col.." / row= "..row.."" transition.to(text,{time=1500, alpha=0}) end --======================================== -- grid code --======================================== local chipWidth = 38 local chipHeight = 38 local colSpace =0 local rowSpace =0 local numCols = 8 local numRows = 8 local centerY=display.contentCenterY local centerX= display.contentCenterX local xPos = centerX- (numCols \* chipWidth + numCols \* colSpace) / 2 local yPos = centerY - (numRows \* chipHeight + numRows \* rowSpace) / 2 --clear table and respawn, display objects have already been removed in "startGame" when the DisplayGroup was cleared/removed T = nil T = {} for col=1,numCols do T[col] = {} --creates an indexed table for each col for row=1, numRows do T[col][row] = {} --creates an indexed table for each row in each col, look familiar? --T[1][1] will be the upper left square, T[8][8] will be the lower right square T[col][row]= display.newRect(0,0,chipWidth,chipHeight) T[col][row].x = xPos + col \* (chipWidth + colSpace) - chipWidth/2 - colSpace T[col][row].y = yPos + row\* (chipHeight + rowSpace) - chipHeight/2 - rowSpace T[col][row]:setFillColor(0.3, 0.6, 0.8) T[col][row].alpha=0.5 T[col][row].gridPos = {x=col, y=row} -- I'm going to seperate the gridPos references, it may be easier, not sure yet' T[col][row].col = col T[col][row].row = row T[col][row].state="blank" T[col][row].originColor = "Void" --will store the player color when first played T[col][row].originPlayCount = 0 --will store the index when first played T[col][row]:addEventListener("tap",chipTapped) DisplayGroup:insert(T[col][row]) --add object to the display group T[col][row].Chip = display.newCircle(cx,cy,15) T[col][row].Chip:setFillColor(1) T[col][row].Chip.x = T[col][row].x T[col][row].Chip.y = T[col][row].y --T[col][row].Chip.width=event.target.width --T[col][row].Chip.height=event.target.height T[col][row].Chip.isVisible = false -- hide the Chip until played DisplayGroup:insert(T[col][row].Chip) end end text = display.newText( "Void", 0, 0, "Helvetica", 24 ) text.x = display.contentCenterX-60 --text.y = display.contentCenterY-60 text.y = 60 text.alpha=1 text:setTextColor(255, 254, 185) DisplayGroup:insert(text) transition.to(text,{time=1500, alpha=0}) local function start() T[4][5].originColor="black" T[4][5].originPlayCount = playCount T[4][5].Chip:setFillColor(0) T[4][5].Chip.isVisible = true T[4][5].state="black" T[4][5].originColor = "black" T[4][5].originPlayCount = 0 T[5][4].originColor="black" T[5][4].originPlayCount = playCount T[5][4].Chip:setFillColor(0) T[5][4].Chip.isVisible = true T[5][4].state="black" T[5][4].originColor = "black" T[5][4].originPlayCount = 0 T[5][5].originColor="white" T[5][5].originPlayCount = playCount T[5][5].Chip:setFillColor(1) T[5][5].Chip.isVisible = true T[5][5].state="white" T[5][5].originColor = "white" T[5][5].originPlayCount = 0 T[4][4].originColor="white" T[4][4].originPlayCount = playCount T[4][4].Chip:setFillColor(1) T[4][4].Chip.isVisible = true T[4][4].state="white" T[4][4].originColor = "white" T[4][4].originPlayCount = 0 end start() end
I changed the .state variable so it’s value is a string, either “blank”, “white”, or “black” so we can compare strings to determine the current color of the Chip. This is the variable we will look at when we determine if a play is valid and if adjacent Chips need to be “captured” or “flipped”.
I also corrected the colors of the start chips, you had them reversed.
Review these changes so you understand the changes and why.
Nail
the function OB:get_valid_moves(player) you posted will have to be totally modified as it calls other functions I have not seen and uses the cells x,y values to determine if other cells are found along the same vectors I believe. I’m not sure how this works from the code posted so far.
The method I have in mind to determine if a play is valid and if there are Chips to be captured will iterate over the indexes of the adjacent cells. I’m not sure this is the best method, but I think it will work.
As you see, there are different ways to accomplish things when programming, some are better than others and some turn out ot be dead ends. this is programming, it’s a game, a puzzle that must be solved. In my opinion, coding is the ultimate game.
I’m imagining the new validPlay() we will write to work like this…
Since we will know the col and row of the cell in play, we will look at the cell vertically above it to see if it is the opposite color and then look at the next cell to see if it is the color in play. If these conditions are found true, the Chip above will be captured.
We will do this with for loops and they will look at all 8 possible directions from the cell in play.
I suggest the 8 possible directions or vectors around the cell in play should be labeled.
If we start Up from the cell in play and rotate clockwise through the vectors we could use these 8 labels.
Up
UpRight - this is the diagonal
Right
DownRight - diagonal
Down
DownLeft - diagonal
Left
UpLeft - diagonal
does this make sense?
Nail
I also added grid lines to the cells to make the game board clear.
Replace these lines in the file.
T[col][row]= display.newRect(0,0,chipWidth,chipHeight) T[col][row].x = xPos + col \* (chipWidth + colSpace) - chipWidth/2 - colSpace T[col][row].y = yPos + row\* (chipHeight + rowSpace) - chipHeight/2 - rowSpace T[col][row].strokeWidth = 3 --add grid lines T[col][row]:setStrokeColor(0) --sets grid color black T[col][row]:setFillColor(0.3, 0.6, 0.8) T[col][row].alpha=0.5 T[col][row].gridPos = {x=col, y=row} -- I'm going to seperate the gridPos references, it may be easier, not sure yet' T[col][row].col = col T[col][row].row = row T[col][row].state="blank" T[col][row].originColor = "Void" --will store the player color when first played T[col][row].originPlayCount = 0 --will store the index when first played T[col][row]:addEventListener("tap",chipTapped) DisplayGroup:insert(T[col][row]) --add object to the display group
Nail