This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Negeator's profile picture

Connect 4

Started by Negeator, 02 May 2012 - 12:42 AM
Negeator #1
Posted 02 May 2012 - 02:42 AM
Connect-4
—————————–

Long gone are the days of playing Connect 4 with sand and gravel. Now you can play Connect 4 on your computer in Minecraft!

There currently is only local play, but I plan to add wireless rednet support soon. This program also outputs to a monitor if you have one, and if your monitor is large enough it'll automatically center things the best it can. There also is a brief help page with the controls and how to play the game. The game is played with nice user-interface using the arrow keys and enter.

PICTURES:
Spoiler


NOTE: Monitor looks glitchy, but that is an issue with my graphics settings on Minecraft, not the program.


CODE:
Spoiler

--[[
		  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()

Be sure to post any bugs/errors if you find any!
Zalerinian #2
Posted 02 May 2012 - 03:20 AM
Very nice, Good job on making the game so nicely.
Klausar #3
Posted 25 June 2012 - 04:53 PM
I get an error when Player 1 wins,

:240: attempt to perform arithmetic __sub on nil and number
Hunterfg09 #4
Posted 30 March 2013 - 04:29 AM
I get this error.

bios:338: [string "Connect4"]:60: ")" expected

ive gone through the code i have written twice now and cannot find anything missing.

ive only gotten up to this line in the code

–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

so im not sure if anything after that fixes this problem
PixelToast #5
Posted 30 March 2013 - 04:30 AM
color would be nice 0 and o hurts my eyes >_>
Dlcruz129 #6
Posted 31 March 2013 - 07:54 PM
color would be nice 0 and o hurts my eyes >_>

This is from May of last year. -_-/>