Jump to content




Problem with Connect 4 game


  • You cannot reply to this topic
5 replies to this topic

#1 Klausar

  • Members
  • 110 posts

Posted 25 June 2012 - 03:57 PM

So I use this code for Connect 4:

--[[
				  CONNECT-4
				  By: Negeator
]]--
--[[
  Declare Variables
--]]
--Whose turn it is
local turn
--Cursor position
local cursorPos
--Message if piece is placed in the wrong place
local errorMessage
--Whether the game is playing
local gamePlaying
--Monitor Side being used
local monSide = "none"
--The monitor
local monitor
--Monitor width and height
local monWidth, monHeight
--Make a 7x6 Grid for the board
local grid =
{
  { " "," "," "," "," "," "," " },
  { " "," "," "," "," "," "," " },
  { " "," "," "," "," "," "," " },
  { " "," "," "," "," "," "," " },
  { " "," "," "," "," "," "," " },
  { " "," "," "," "," "," "," " },
}
local menuOptions =
{
  "Local Game", "Help", "Quit"
}
--[[
  Functions
--]]
--Main Function
function main()
  cursorPos = 1
  while true do
		menuDraw()
menuInput()
  end
end
--Events for the main menu (mainly input)
function menuInput()
  event, p1, p2 = os.pullEvent()
  if event == "key" then
   --Up
		if p1 == 200 then
   cursorPos = cursorPos - 1
   if cursorPos < 1 then
		 cursorPos = 3
   end

--Down
elseif p1 == 208 then
   cursorPos = cursorPos + 1
   if cursorPos > 3 then
		 cursorPos = 1
   end

--Enter
elseif p1 == 28 then
   if cursorPos == 1 then
		 game()
   elseif cursorPos == 2 then
		 help()
   elseif cursorPos == 3 then
		 clearScreen()
  error()
   end

end
  end
end
--Draws the main menu
function menuDraw()
  clearScreen()
  drawAt(1,1,"Connect-4")
  drawAt(1,2,"------------------")
  for i = 1, 3 do
		drawAt(4,i + 2,menuOptions[i])
  end
  drawAt(1,cursorPos + 2,"[*]")
end
function help()
  clearScreen()
  drawAt(1,1,"Connect-4 - Help:")
  drawAt(1,2,"------------------")
  drawAt(1,3,"Players take turn placing their pieces")
  drawAt(1,4,"in collumns.  The piece falls until it hits")
  drawAt(1,5,"the bottom or another piece.  The first player")
  drawAt(1,6,"to get 4 in a row in any direction wins!")
  drawAt(1,7,"Use arrow keys to select the row.")
  drawAt(1,8,"Press Enter to place a piece.")
  waitAtEnd()
end
--Play the game
function game()
  --Reset some variables
  gamePlaying = true
  turn = 0
  cursorPos = 1
  errorMessage = ""
  resetBoard()
  startMonitor()
  while gamePlaying == true do
		gameDraw()
		gameEvent()
checkForWinner()
  end
  waitAtEnd()
  cursorPos = 1
end
function waitAtEnd()
  drawAt(1,18,"Press Enter to Exit.")
  while true do
		event, key = os.pullEvent()
if event == "key" then
   if key == 28 then
		 return
   end
end
  end
end
--Draw the game
function gameDraw()
  clearScreen()
  drawBoard()
  --Draw the cursor
  drawAt((cursorPos * 3) + 11,1," | ")
  drawAt((cursorPos * 3) + 11,2," V ")
  if turn == 0 then
		drawAt(1,15,"Turn: Player 1")
  else
		drawAt(1,15,"Turn: Player 2")
  end
  drawAt(1,17,errorMessage)
  if monSide ~= "none" then
		drawMonitor()
  end
end
--Manages events for the game
function gameEvent()
  event, p1, p2 = os.pullEvent()
  if event == "key" then
		--Left
		if p1 == 203 then
   cursorPos = cursorPos - 1
   if cursorPos < 1 then
		 cursorPos = 7
   end

--Right
elseif p1 == 205 then
   cursorPos = cursorPos + 1
   if cursorPos > 7 then
		 cursorPos = 1
   end

--Backspace
elseif p1 == 14 then
   gamePlaying = false
   drawAt(1,17,"Game Terminated.")
--Enter
elseif p1 == 28 then
		if place(cursorPos) == true then
		  errorMessage = ""
		else
		  errorMessage = "Piece does not fit."
		end
end
  end
end
--Draw the board
function drawBoard()
  for x = 1, 7 do
		for y = 1, 6 do
   drawAt((x * 3) + 11,y * 2 + 1,"("..grid[y][x]..")")
end
  end
end
--Place a game piece.  Returns a boolean based on whether a piece was successfully placed.
function place(x)
  local y = 6
  while y >= 1 do
		if grid[y][x] == " " then
   if turn == 0 then
		 grid[y][x] = "0"
				turn = 1
   else
		 grid[y][x] = "o"
  turn = 0
   end

   return true
end
y = y - 1
  end
  sleep(.2)
  return false
end
--Check for a winner
function checkForWinner()
  local pivotX, pivotY
  for x = 1, 7 do
		for y = 1, 6 do
   pivotX = x
   pivotY = y
   if checkAtPoint(x,y,"0") == true then
		 gameDraw()
		 drawAt(1,17,"Player 1 Wins!")
  if monSide ~= "none" then
		drawAtMonitor(2,monHeight - 1, "Player 1 Wins!")
  end
  gamePlaying = false
   elseif checkAtPoint(x,y,"o") == true then
		 gameDraw()
  if monSide ~= "none" then
		  drawAt(1,17,"Player 2 Wins!")
  end
  drawAtMonitor(2,monHeight - 1, "Player 2 Wins!")
  gamePlaying = false
   end

end
  end
end
--Checks for any connect 4's at a position.  Returns true or false based on if it finds a connect 4.
function checkAtPoint(x,y,symbol)
  local checkX = x
  local checkY = y
  for dir = 0, 7 do
		x = checkX
y = checkY
		for i = 1, 4 do
  if x < 1 or x > 7 or y < 1 or y > 6 then
		 i = 4
		 elseif grid[y][x] == symbol then
		   if i < 4 then
		  x , y = addDir(x,y,dir)
		else
				--We found 4 in a row!
				return true
		end
  else
		i = 4
  end
		end
  end
  return false
end
--returns a modifier to the x and y value given a direction.  This is used to find the next point given a direction.
function addDir(x,y,direction)
  if direction == 0 then
		return x + 0,y + -1
  elseif direction == 1 then
		return x + 1,y + -1
  elseif direction == 2 then
		return x + 1,y + 0
  elseif direction == 3 then
		return x + 1,y + -1
  elseif direction == 4 then
		return x + 0,y + -1
  elseif direction == 5 then
		return x + -1,y + -1
  elseif direction == 6 then
		return x + -1,y + -1
  elseif direction == 7 then
		return -x + 1,y + -1
  end
end
--Reset the board
function resetBoard()
  for x = 1, 7 do
		for y = 1, 6 do
		grid[y][x] = " "
end
  end
end
--Draw the monitor
function drawMonitor()
  monWidth, monHeight = monitor.getSize()
  gridWidth = 21 --This is the width of the grid
  gridHeight = 11 --This is the height of the grid
  xAdd = (monWidth/2) - (gridWidth/2) - 3
  yAdd = (monHeight/2) - (gridHeight/2) - 2
  clearMonitor()
  for x = 1, 7 do
		for y = 1, 6 do
		  drawAtMonitor( xAdd + (3 * x), yAdd + (y * 2), "("..grid[y][x]..")")
end
  end
  if turn == 0 then
   drawAtMonitor(2,monHeight - 1, "Turn: Player 1")
  else
		drawAtMonitor(2,monHeight - 1, "Turn: Player 2")
  end
end
--If there is a monitor, set it up
function startMonitor()
  for i=1,#rs.getSides() do
		if peripheral.isPresent(rs.getSides()[i]) and peripheral.getType(rs.getSides()[i]) == "monitor" then
   monSide = rs.getSides()[i]
   monitor = peripheral.wrap( monSide )
   return
end
  end
  monSide = "none"
end
--Clear the terminal screen
function clearScreen()
  term.clear()
  term.setCursorPos(1,1)
end
--Draw text at a position on the terminal screen
function drawAt(x,y,text)
  term.setCursorPos(x,y)
  term.write(text)
end
--Basic Monitor Draw Functions
function clearMonitor()
  monitor.clear()
  monitor.setCursorPos(1,1)
end
function drawAtMonitor(x,y,text)
  monitor.setCursorPos(x,y)
  monitor.write(text)
end
--[[
  Run the Program!
--]]
main()

But I keep getting this error when Player 1 wins:

:240: attempt to perform arithmetic __sub on nil and number

How can I fix it?

#2 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 25 June 2012 - 06:01 PM

I don't have any easy way to determine line numbers on my phone, but I would suspect that you may have monHeight as nil there.

Also, variables that are declared should usually be set to some sane value at time of declaration. Additionally, please double-check your logic in the function which checks for and declares wins. I think you've got player two's monitor and non-monitor draws wrong.

More details would be good also. What happens when player two wins? What size monitor are you using? What is the value of monHeight in that function?

#3 Klausar

  • Members
  • 110 posts

Posted 25 June 2012 - 06:22 PM

When player two wins everything it is fine, it just says "Player two wins". It isn't my code so I can't tell you the coder stuff. I don't use a monitor and I don't want to, both player play on one computer. How does the code have to look to work?

#4 Klausar

  • Members
  • 110 posts

Posted 30 June 2012 - 08:53 AM

Can noone help me?

#5 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 30 June 2012 - 09:20 AM

Why don't you ask the person who wrote the code? I'm much more interested in helping people fix their own code and learn something than I am in fixing something for someone that a third party wrote. I imagine others here feel the same way.

#6 Klausar

  • Members
  • 110 posts

Posted 30 June 2012 - 01:20 PM

I did but I think he is inactive. I already tried to fix the code for 1 hour, but I'm not this experienced.





2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users