tech/game

21/07/13 TicTacToe - CHECK WIN LOSE OR DRAW

tech-lover 2021. 7. 13. 17:22

https://youtu.be/R9GvGlAJB9k

https://docs.coronalabs.com/api/library/display/newLine.html

 

Solar2D Documentation — API Reference | Libraries | display | newLine

Overview Draw a line from one point to another. Optionally, you may append points to the end of the line to create outline shapes or paths.

docs.coronalabs.com

 

```

local composer = require( "composer" )

local scene = composer.newScene()

 

-- -----------------------------------------------------------------------------------

-- Code outside of the scene event functions below will only be executed ONCE unless

-- the scene is removed entirely (not recycled) via "composer.removeScene()"

-- -----------------------------------------------------------------------------------

 

local grpBackground

local grpMain

local grpUI

 

local grpBoardBG

local grpBoardFG



local backgroundImage

local gridSquare

 

local imgLogo

local imgGameTitle

 

local arrayBoard = {}

 

local player1

local player2

local playersTurn = math.random(2)

 

local message

local messageOptions = {

    parent = grpUI,

    text = "Hello World",

    x = display.contentCenterX,

    y = display.contentCenterY-210,

    width = display.contentWidth - 20,

    font = "fonts-tictactoe/BradBunR.ttf",

    fontSize = 40,

    align = "center"

}

 

local optionsZeros = 

{

    text = "O",

    x = display.contentCenterX,

    y = display.contentCenterY,

    -- font = native.systemFont,

    font = "fonts-tictactoe/BradBunR.ttf",

    fontSize = 120,

    align = "center"  -- Alignment parameter

}

 

local optionsCrosses = 

{

    text = "X",

    x = display.contentCenterX,

    y = display.contentCenterY,

    font = "fonts-tictactoe/BradBunR.ttf",

    fontSize = 120,

    align = "center"

}

 

-- -----------------------------------------------------------------------------------

-- Scene event functions

-- -----------------------------------------------------------------------------------

 

-- create()

function scene:create( event )

 

    local sceneGroup = self.view

    -- Code here runs when the scene is first created but has not yet appeared on screen

 

    grpBackground = display.newGroup()  

    grpMain = display.newGroup()   

    grpUI = display.newGroup() 

 

    sceneGroup:insert(grpBackground)

    sceneGroup:insert(grpMain)

    sceneGroup:insert(grpUI)

 

    grpBoardBG = display.newGroup() 

    grpBoardFG = display.newGroup() 

    grpMain:insert(grpBoardBG)

    grpBoardBG:insert(grpBoardFG)

 

    grpBoardFG:toBack()

    grpBoardFG:toFront()

 

    backgroundImage = display.newImageRect(grpBackground, "images-tictactoe/background-orange.jpg"7681024)

    backgroundImage.x = display.contentCenterX

    backgroundImage.y = display.contentCenterY

 

    local gridBoarder = display.newRect(grpBoardBG, display.contentCenterX, display.contentCenterY, 300300)

    gridBoarder.alpha = 0.5

    gridBoarder:toBack()

    gridBoarder:setFillColor(1110.1)

    gridBoarder.strokeWidth = 10

    gridBoarder:setStrokeColor(00.50.5)

 

    local imgLogo = display.newImageRect(grpMain, "images-tictactoe/logo.png"

    7070)

    imgLogo.x = display.contentCenterX - 130

    imgLogo.y = display.contentCenterY - 300

    imgLogo:rotate(-10)

    imgLogo:setFillColor(0.50.51)

 

    local imgGameTitle = display.newImageRect(grpMain, "images-tictactoe/game-studio.png"1000/5358/5)

    imgGameTitle.x = display.contentCenterX + 10

    imgGameTitle.y = display.contentCenterY - 300

    imgGameTitle:setFillColor(0.511)

 

    message = display.newText(messageOptions)

 

    player1 = display.newText(messageOptions)

    player1.playerNum = 1

    player1.character = "zeros"

    player1.name = "Player 1"

    player1.isVisible = false

 

    player2 = display.newText(messageOptions)

    player2.playerNum = 2

    player2.character = "crosses"

    player2.name = "Player 2"

    player2.isVisible = false



end

 

 

-- show()

function scene:show( event )

 

    local sceneGroup = self.view

    local phase = event.phase

 

    if ( phase == "will" ) then

        -- Code here runs when the scene is still off screen (but is about to come on screen)



        local counterSquareNumber = 1

        local function drawSquare(xPosIn, yPosIn)

            print("sqaure")

            gridSquare = display.newRect(grpBoardBG, xPosIn, yPosIn, 100100)

            gridSquare.strokeWidth = 3

            gridSquare:setStrokeColor( 000)

            gridSquare.isVisible = true

            gridSquare:toBack() 

            gridSquare.number = counterSquareNumber

            gridSquare.status = "EMPTY"

            table.insert( arrayBoard, counterSquareNumber, gridSquare)

 

            counterSquareNumber = counterSquareNumber + 1

 

        end



        local function drawRow(xPosIn, yPosIn) 

            print("drawRow()")

 

            local numCols = 3

            local xPos = xPosIn

            local yPos = yPosIn

 

            for count=1, numCols, 1 do

                print("for loop")

 

                drawSquare(xPos, yPos)

                xPos = xPos + 100



            end

 

        end

 

        local function drawGrid(xPosIn, yPosIn)

            print("drawGrid()")

 

            local numRows = 3

            local xPos = xPosIn

            local yPos = yPosIn

 

            for count=1, numRows, 1 do

            

                print("for loop rows")

                drawRow(xPos, yPos)

                yPos = yPos + 100

 

            end

 

        end

 

        -- Starting box coordinates (top left box 1)

        local xPos = display.contentCenterX - 100

        local yPos = display.contentCenterY - 100

        drawGrid(xPos, yPos)

 

        grpBoardBG.y = grpBoardBG.y + 20

 

        message.text = "It's Player " .. playersTurn .. "'s Turn"

 

    elseif ( phase == "did" ) then

        -- Code here runs when the scene is entirely on screen

 

        local function drawZeros(xPosIn, yPosIn)

                

            local charZeros = display.newText( optionsZeros )

            grpBoardFG:insert(charZeros)

            charZeros:setFillColor( 10.20.1 )

            charZeros.isVisible = true

            charZeros:toFront()

            charZeros.x = xPosIn

            charZeros.y = yPosIn -5

        end

    

        local function drawCrosses(xPosIn, yPosIn)

            local charCrosses = display.newText( optionsCrosses )

            grpBoardFG:insert(charCrosses)

            charCrosses:setFillColor( 0.10.51 )

            charCrosses.isVisible = true        

            charCrosses:toFront()

            charCrosses.x = xPosIn

            charCrosses.y = yPosIn -5

        end

 

        local function drawWinningLine(startX, startY, endX, endY)

            print("drawWinningLine")

            local line = display.newLine(grpBoardFG, startX, startY, endX, endY)

            line:setStrokeColor(0000.5)

            line.strokeWidth = 30

            line:toFront()

 

            return true

        end

 

        local function checkWinLoseDraw(characterIn)

            print("checkWinLoseDraw: "..tostring(characterIn))

 

            local numEmptySquares = 9

            local result = false

 

            local obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9

 

            for index, object in ipairs (arrayBoard) do

 

                print("["..index.."]"..object.number, object.status)

 

                local function checkStatus(statusIn)

                    if statusIn ~= "EMPTY" then

                        numEmptySquares = numEmptySquares - 1

                        print("numEmptySquares: "..numEmptySquares)

                    else

                        -- do nothing

                    end

                end

 

                if object.number == 1 then obj1 = object checkStatus(object.status)

                elseif object.number == 2 then obj2 = object checkStatus(object.status)

                elseif object.number == 3 then obj3 = object checkStatus(object.status)

                elseif object.number == 4 then obj4 = object checkStatus(object.status)

                elseif object.number == 5 then obj5 = object checkStatus(object.status)

                elseif object.number == 6 then obj6 = object checkStatus(object.status)

                elseif object.number == 7 then obj7 = object checkStatus(object.status)

                elseif object.number == 8 then obj8 = object checkStatus(object.status)

                elseif object.number == 9 then obj9 = object checkStatus(object.status)

                else

                    -- error

                end

            end

 

            -- horizontal pattern 3 x mathing characters

            --H1

            if (characterIn == obj1.status) and (characterIn == obj2.status) and (characterIn == obj3.status) then

                print("winning line H1")

                result = drawWinningLine(obj1.x, obj1.y, obj3.x, obj3.y)

            --H2

            elseif (characterIn == obj4.status) and (characterIn == obj5.status) and (characterIn == obj6.status) then

                print("winning line H1")     

                result = drawWinningLine(obj4.x, obj4.y, obj6.x, obj6.y)

       

            --H3

            elseif (characterIn == obj7.status) and (characterIn == obj8.status) and (characterIn == obj9.status) then

                print("winning line H1")

                result = drawWinningLine(obj7.x, obj7.y, obj9.x, obj9.y)

 

            end            



            -- vertical patterns 3 x matching characters

            --V1

            if (characterIn == obj1.status) and (characterIn == obj4.status) and (characterIn == obj7.status) then

                print("winning line V1")

                result = drawWinningLine(obj1.x, obj1.y, obj7.x, obj7.y)

            --V2                

            elseif (characterIn == obj2.status) and (characterIn == obj5.status) and (characterIn == obj8.status) then

                print("winning line V2")            

                result = drawWinningLine(obj2.x, obj2.y, obj8.x, obj8.y)

            --V2

            elseif (characterIn == obj3.status) and (characterIn == obj6.status) and (characterIn == obj9.status) then

                print("winning line V3")

                result = drawWinningLine(obj3.x, obj3.y, obj9.x, obj9.y)

            end       

 

            -- diagonal patterns 3 x matching characters

            --D1

            if (characterIn == obj1.status) and (characterIn == obj5.status) and (characterIn == obj9.status) then

                print("winning line D1")

                result = drawWinningLine(obj1.x, obj1.y, obj9.x, obj9.y)            

            --D2

            elseif (characterIn == obj3.status) and (characterIn == obj5.status) and (characterIn == obj7.status) then

                print("winning line D2")

                result = drawWinningLine(obj3.x, obj3.y, obj7.x, obj7.y)

            end        

            

            print(result)

            if (result == false) and (numEmptySquares == 0then

                print("DRAW")

                message.text = "Oh No, Draw!!"

            end

 

        end

        

        local function whichSquareTapped(event)

            print("square number is: " .. event.target.number)

            print("playersTurn ".. playersTurn)

 

            local xPos = event.target.x

            local yPos = event.target.y

 

            local function updateSquareStatus(inCharacter)

                print("updateSquareStatus")

                local character = tostring(inCharacter)

                for index, object in ipairs (arrayBoard) do

                    if object.number == event.target.number then

                        print("match")

                        print("object.status: "..object.status)

 

                        if object.status == "EMPTY" then

                            object.status = character

                            if character == "zeros" then

                                drawZeros(xPos, yPos)

                                checkWinLoseDraw(character)

                                playersTurn = 2

                                message.text = "It's Player " .. playersTurn .. "'s Turn"

 

                            elseif character == "crosses" then

                                drawCrosses(xPos, yPos)

                                checkWinLoseDraw(character)

                                playersTurn = 1

                                message.text = "It's Player " .. playersTurn .. "'s Turn"                               

                            end

                        elseif object.status ~= "EMPTY" then

                            message.text = "Choose Another"

                        else

                            message.text = "???"

                        end

 

                    else

                        -- print("non match")

                    end

                    print("["..index.."]"..object.number, object.status)

                end

                character = nil

            end



            if playersTurn == player1.playerNum then

                print("player1.playerNum ".. player1.playerNum)

                print("player1.character ".. player1.character)

 

                updateSquareStatus(player1.character)

 

            elseif playersTurn == player2.playerNum then

                print("player2.playerNum ".. player2.playerNum)

                print("player2.character ".. player2.character)

 

                updateSquareStatus(player2.character)

 

            else

                -- error do nothing

            end




        end

 

        for index, value in ipairs(arrayBoard) do

            local objSquare = value

 

            print("[" .. index .. "] " .. objSquare.number)

            objSquare:addEventListener("tap", whichSquareTapped)

 

        end



    end

end

 

 

-- hide()

function scene:hide( event )

 

    local sceneGroup = self.view

    local phase = event.phase

 

    if ( phase == "will" ) then

        -- Code here runs when the scene is on screen (but is about to go off screen)

 

    elseif ( phase == "did" ) then

        -- Code here runs immediately after the scene goes entirely off screen

 

    end

end

 

 

-- destroy()

function scene:destroy( event )

 

    local sceneGroup = self.view

    -- Code here runs prior to the removal of scene's view

 

end

 

 

-- -----------------------------------------------------------------------------------

-- Scene event function listeners

-- -----------------------------------------------------------------------------------

scene:addEventListener( "create", scene )

scene:addEventListener( "show", scene )

scene:addEventListener( "hide", scene )

scene:addEventListener( "destroy", scene )

-- -----------------------------------------------------------------------------------

 

return scene

```