Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Othello = class()
- --unfinished, typed in scite, do not use, etc
- player = 0
- empty = 0.5
- ai = 1
- up = vec2(0,1)
- down = -up
- right = vec2(1,0)
- left = -right
- directions = { right, right+up, up, up+left, left, left+down, down, down+right }
- zero = vec2(0,0)
- function Othello:init(x,y)
- self.turn = player
- self.gameOver = false
- self.winner = empty
- self.size = vec2(x,y)
- self.pieces = {}
- self.pieces = make2dTable(self.pieces, self.size, empty)
- mid = vec2(math.floor(self.size.x /2), math.floor(self.size.y /2))
- self.pieces[mid.x][mid.y] = self.turn
- self.pieces[mid.x+1][mid.y+1] = self.turn
- self.pieces[mid.x+1][mid.y] = (self.turn+1)%2
- self.pieces[mid.x][mid.y+1] = (self.turn+1)%2
- self.moves = { {}, {} }
- self.potential = vec2(0,0)
- self.last = nil
- self:updateAvailableMoves(ai)
- self:updateAvailableMoves(player)
- end
- function Othello:copy(orig)
- self.turn = orig.turn
- self.gameOver = orig.gameOver
- self.winner = orig.winner
- self.size = orig.size
- self.pieces = {}
- for i,c in pairs(orig.pieces) do
- local temp = {}
- for k,v in pairs(c) do
- table.insert(temp, k)
- end
- table.insert(self.pieces, temp)
- end
- self:updateAvailableMoves(ai)
- self:updateAvailableMoves(player)
- end
- function Othello:draw()
- bgColor = white
- if self.turn == player then
- bgColor = color(red.r/2, red.g/2, red.b/2)
- else
- bgColor = color(blue.r/2, blue.g/2, blue.b/2)
- end
- background(bgColor)
- dx = WIDTH / self.size.x
- dy = HEIGHT / self.size.y
- ellipseMode(CORNERS)
- for i,c in pairs(self.pieces) do
- for j,r in pairs(self.pieces[i]) do
- pushMatrix()
- translate((i-1)*dx, (j-1)*dy)
- if self.pieces[i][j] == player then fill(red)
- elseif self.pieces[i][j] == ai then fill(blue)
- else fill(gray) end
- ellipse(0,0, dx,dy)
- popMatrix()
- end
- end
- end
- function Othello:resetChain()
- self.potential.x = 0
- self.potential.y = 0
- self.last = nil
- end
- function Othello:countChain(i,j)
- if i < 1 or self.size.x < i then return
- elseif j < 1 or self.size.y < j then return end
- if self.potential.x == 0 then
- if self.pieces[i][j] == empty then
- self:resetChain()
- end
- else
- if last == nil then
- if self.pieces[i][j] == empty then
- self.potential = vec2(i,j)
- self.last = nil
- else
- self.last = self.pieces[i][j]
- end
- elseif self.last == self.pieces[i][j] then
- -- do nothing
- elseif self.pieces[i][j] == empty then
- self:resetChain()
- else
- table.insert(self.moves[1+((last+1)%2)], vec2(potential.x, potential.y))
- self:resetChain()
- end
- end
- end
- function make2dTable(myTable, size, default)
- for i = 1, size.x do
- local temp = {}
- for j = 1, size.y do
- table.insert(temp, j, default)
- end
- table.insert(myTable, i, temp)
- end
- return myTable
- end
- function Othello:nextTurn()
- self.turn = (self.turn+1)%2
- if #self.moves[self.turn+1] == 0 then
- self.turn = (self.turn+1)%2
- end
- end
- function Othello:move(x,y)
- -- print("in move")
- --print(x.." "..y)
- for i,move in pairs(self.moves[self.turn+1]) do
- if self.moves[self.turn+1][i].x == x then
- if self.moves[self.turn+1][i].y == y then
- -- if statement broken up for space constraints
- self.pieces[x][y] = self.turn
- --print(self.turn)
- self:flipStones(x,y,self.turn,(self.turn+1)%2)
- self.turn = (self.turn+1)%2
- self:updateAvailableMoves(self.turn)
- return
- end
- end
- end
- print("error: move ("..x..","..y..") not valid?")
- -- self:printValid()
- end
- function Othello:printValid()
- self:updateAvailableMoves(player)
- self:updateAvailableMoves(ai)
- print("turn is "..self.turn)
- for n = 0,1 do
- print("valid moves for player "..n.." are:")
- for k,v in pairs(self.moves[n+1]) do
- print(v)
- end
- end
- end
- function Othello:touched(t)
- pos = vec2(0,0)
- pos.x = math.ceil(self.size.x * t.x/WIDTH)
- pos.y = math.ceil(self.size.y * t.y/HEIGHT)
- if self.pieces[pos.x][pos.y] == empty then
- self:move(pos.x,pos.y)
- else
- print("error: location already occupied.")
- end
- end
- function Othello:allStones(side)
- local found = {}
- for i,c in pairs(self.pieces) do
- for j,p in pairs(self.pieces[i]) do
- if p == side then table.insert(found,vec2(i,j)) end
- end
- end
- return found
- end
- function Othello:updateAvailableMoves(side)
- --print("updating")
- local otherSide = (side+1)%2
- self.moves[side+1] = {}
- local myStones = self:allStones(side)
- for k,stone in pairs(myStones) do
- --print("im checking a stone")
- for dirNum,direction in pairs(directions) do
- --print("checking direction...")
- --print(direction)
- self.last = nil
- found = nil
- i = stone.x
- j = stone.y
- while (found == nil) do
- i = i + direction.x
- j = j + direction.y
- found = self:countChain2(i, j, side, otherSide)
- end
- if found then
- --print("got one")
- table.insert(self.moves[side+1], vec2(i,j))
- end
- end
- end
- end
- -- return false := chain definitely not found
- -- return nil := chain ongoing
- -- return true := chain found
- function Othello:countChain2(i,j, side, otherSide)
- if not self:validCoords(i,j) then return false end
- if self.last == nil then
- if self.pieces[i][j] == otherSide then
- self.last = otherSide
- return nil
- else
- return false
- end
- else
- if self.pieces[i][j] == empty then return true end
- if self.pieces[i][j] == otherSide then return nil end
- return false
- end
- end
- function Othello:flipStones(x,y,side,otherSide)
- --print("in flip")
- --print(side)
- for dirNum,direction in pairs(directions) do
- local stonesToFlip = {}
- local keepOn = true
- local i = x + direction.x
- local j = y + direction.y
- local doFlip = false
- while self:validCoords(i,j) and keepOn do
- if self.pieces[i][j] == side then
- keepOn = false
- doFlip = true
- end
- if self.pieces[i][j] == empty then
- keepOn = false
- end
- if keepOn then
- table.insert(stonesToFlip, vec2(i,j))
- i = i + direction.x
- j = j + direction.y
- end
- end
- if doFlip then
- for k,v in pairs(stonesToFlip) do
- --print(v)
- --print(i.." ij "..j)
- self.pieces[v.x][v.y] = side
- end
- -- stonesToFlip = {}
- end
- end
- end
- function Othello:validCoords(i,j)
- if (0<i and i<=self.size.x and 0<j and j<=self.size.y) then
- return true
- else
- return false
- end
- end
- function Othello:randomMove()
- local myMove = math.random(#self.moves[self.turn+1])
- -- print("in randommove")
- -- print(myMove)
- -- print(#self.moves[self.turn+1])
- -- print(self.moves[self.turn+1][myMove].x .." ".. self.moves[self.turn+1][myMove].y)
- self:move(self.moves[self.turn+1][myMove].x, self.moves[self.turn+1][myMove].y)
- end
- function Othello:positionStrength()
- local score = {0,0}
- for i,c in pairs(self.pieces) do
- for j,p in pairs(c) do
- if p == player then
- score[player+1] = score[player+1] + 1
- elseif p == ai then
- score[ai+1] = score[ai+1] + 1
- end
- end
- end
- return score[ai+1] / (score[player+1] + score[ai+1])
- end
- function Othello:gameOver()
- if self.gameOver then return true end
- if (#self.moves[self.turn+1] == 0) then
- self.gameOver = true
- local str = self:positionStrength()
- if str < 0.5 then
- self.winner = player
- elseif 0.5 < str then
- self.winner = ai
- else
- self.winner = tie
- end
- end
- return self.gameOver
- end
- --[[
- -------
- R------
- B--RB--
- R--BR--
- BRRRR-B
- BBBRB-R
- --]]
Advertisement
Add Comment
Please, Sign In to add comment