Skip to content

Instantly share code, notes, and snippets.

@yurapyon
Last active June 23, 2016 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yurapyon/3fb96709ba486047516bbbadff66ebff to your computer and use it in GitHub Desktop.
Save yurapyon/3fb96709ba486047516bbbadff66ebff to your computer and use it in GitHub Desktop.
tic tac toe
local string = require"string"
local fmt = string.format
--on adding computer player
-- math.random(upper)
-- math.random(lower, upper)
-- ==&== BOARD ==&==
local function new_board()
return {{" "," "," "},
{" "," "," "},
{" "," "," "}}
end
local function print_board(board)
local function print_row(row)
for col = 1,2 do
io.write(fmt(" %s |",board[row][col]))
end
io.write(fmt(" %s \n", board[row][3]))
end
for row = 1, 2 do
print_row(row)
io.write("___|___|___\n")
end
print_row(3)
io.write(" | | \n")
end
-- ==&== CHECK ==&==
--NOTE: for check functions:
--returns nil for no matches or match of " "
-- players letter for match of anything else
local function check_col(board, col)
for row = 1, 2 do
if board[row][col] ~= board[row+1][col] then
return nil
end
end
if board [1][col] ~= " " then
return board[1][col]
end
return nil
end
local function check_row(board, row)
for col = 1, 2 do
if board[row][col] ~= board[row][col+1] then
return nil
end
end
if board [row][1] ~= " " then
return board[row][1]
end
return nil
end
-- NOTE:
-- up diagonal is _ _ X
-- _ X _
-- X _ _
-- not up is the other diagonal
local function check_diag(board, check_up)
if check_up then
if board[1][3] == board[2][2] and board[2][2] == board[3][1] then
if board[2][2] ~= " " then
return board[2][2]
end
end
else
if board[1][1] == board[2][2] and board[2][2] == board[3][3] then
if board[2][2] ~= " " then
return board[2][2]
end
end
end
return nil
end
local function check_board(board)
local ret
for i=1,3 do
ret = ret or check_col(board, i)
ret = ret or check_row(board, i)
end
ret = ret or check_diag(board, true)
ret = ret or check_diag(board, false)
return ret
end
-- ==&== READ ==&==
local function read_for_and_put_coord(board, letter)
while true do
local input = io.read()
if input ~= "" then --just pressing enter does not give error but io.read loop continues
local _, _, x, y = string.find(input, "%s-(%d)%s+(%d)")
x = tonumber(x)
y = tonumber(y)
if x and y then
if x < 4 and x > 0 and y < 4 and y >0 then
--NOTE: coords seem flipped here
-- b/c indexing the board goes
-- [row][column]
-- but in reality x corresponds to col and y corresponds to row
if board[y][x] == " " then
board[y][x] = letter
break
else
io.write("HEY someones already put a letter there!!!\n")
end
else
io.write(fmt("sadly, you cant put your letter at (%d, %d)\n", x, y))
end
else
io.write("you cant put your letter... there...(o.O\n")
end
io.write("please try again...\n")
end
end
end
local function read_for_letter()
while true do
local _,_,ret = string.find(io.read(), "%s-(.)")
if ret then
return ret
end
end
end
-- returns true for yes or false for no
local function read_for_y_or_n(default_to)
if default_to == nil then default_to = false end
while true do
local _, _, ret = string.find(io.read(), "%s-(.)")
if not ret then
return default_to
elseif ret == "y" or ret == "Y" or ret == "yes" then
return true
elseif ret == "n" or ret == "N" or ret == "no" then
return false
else
io.write(fmt("yo idk what '%s' means in this context ? \ntry again pls!\n", ret))
end
end
end
-- ==&== MAIN ==&==
local function main()
io.write" welcome to tic tac toe! \n"
io.write" ~~~~~~~~~~~~~~~~~~~~~~~ \n"
local p1,p2
local choose_letters = true
local first_coord = true
while true do --loop for repeat games
if choose_letters then
io.write"player 1 choose your letter!\n"
p1 = read_for_letter()
if p1 == "x" then
p2 = "o"
elseif p1 == "X" then
p2 = "O"
elseif p1 == "o" then
p2 = "x"
elseif p1 == "O" then
p2 = "X"
else
while true do
io.write("player 2 choose your letter!\n")
p2 = read_for_letter()
if p2 ~= p1 then
break
else
io.write("ya can't pick the same letter as player 1......\n")
end
end
end
end
io.write(fmt("\nplayer 1 is %s's\nplayer 2 is %s's\n", p1, p2))
io.write("lets play!\n\n")
local board = new_board()
local outcome = nil
local p1s_turn = true
local turns = 0
while not outcome do
-- turn
io.write(fmt("%s pick a coordinate...\n", p1s_turn and "player 1" or "player 2"))
if first_coord then
io.write("*whisper* please format your coords as: over#[space]down#\n")
first_coord = false
end
read_for_and_put_coord(board, p1s_turn and p1 or p2)
p1s_turn = not p1s_turn
turns = turns + 1
-- print and chek
print_board(board)
outcome = check_board(board)
if turns >= 9 then
break
end
end
io.write("\nfinissshhh...\n\n")
if not outcome then
io.write("dangg it was a draww..\n")
else
if outcome == p1 then
io.write("o gr8 job player 1! real nice going..\n")
else
io.write("o gr8 job player 2! real nice going..\n")
end
end
io.write("wanna play again, huh? [y,N]\n")
if read_for_y_or_n(false) then
io.write("gr88888888...\n")
io.write("choose new letters? [y,N]\n")
choose_letters = read_for_y_or_n(false)
else
io.write("thanks for playing!\n")
break
end
end
end
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment