From 1abb9a84504b69223a0f1335a4aec6c08becce9d Mon Sep 17 00:00:00 2001 From: LDDestroier Date: Thu, 13 Dec 2018 17:35:47 -0500 Subject: [PATCH] Add files via upload --- connect4.lua | 334 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 connect4.lua diff --git a/connect4.lua b/connect4.lua new file mode 100644 index 0000000..90b2c27 --- /dev/null +++ b/connect4.lua @@ -0,0 +1,334 @@ +local scr_x, scr_y = term.getSize() +local midX, midY = .5 * scr_x, .5 * scr_y +local origTX, origBG = term.getTextColor(), term.getBackgroundColor() + +local sleepDelay = 0.05 + +local board = {} -- connect 4 board; formatted like board[y][x] +local block = {} -- bottom blockage; formatted like block[x] + +local waiting = false + +local boardX, boardY = 7, 6 -- size of board + +local palette = { + bg = colors.black, -- color of backdrop + board = colors.white, -- color of board + txt = colors.white -- color of text +} + +local tiles = { + ["bl"] = palette.bg, -- blank space + ["P1"] = colors.red, -- player 1 + ["P2"] = colors.blue -- player 2 +} + +local you = "P1" +local nou = "P2" + +local cwrite = function(text, y) + local cx, cy = term.getCursorPos() + term.setCursorPos(midX - math.floor(#text / 2), y or cy) + term.write(text) +end + +local cblit = function(char, text, back, y) + local cx, cy = term.getCursorPos() + term.setCursorPos(midX - math.floor(#text / 2), y or cy) + term.blit(char, text, back) +end + +local resetBoard = function() + board = {} + for y = 1, boardY do + board[y] = {} + for x = 1, boardX do + board[y][x] = {"bl", 0} -- owner, half-in mod + end + end + for x = 1, boardX do + block[x] = true + end +end + +local addPiece = function(owner, x) + if board[1][x][1] == "bl" then + board[1][x] = {owner, 0, x, -1} + return true + else + return false + end +end + +local moveTilesDown = function() + local settled = true -- allows for animated falling tiles + for y = boardY, 1, -1 do + for x = 1, boardX do + if board[y][x][1] ~= "bl" then + if board[y][x][2] == -1 then + board[y][x][2] = 0 + settled = false + elseif (y + 1 <= boardY) then + if board[y + 1][x][1] == "bl" then + if board[y][x][2] == 0 then + board[y][x][2] = 1 + settled = false + elseif board[y][x][2] == 1 then + board[y + 1][x] = {board[y][x][1], -1, x, y + 1} + board[y][x] = {"bl", 0, x, y} + settled = false + end + end + elseif not block[x] then + if board[y][x][2] == 0 then + board[y][x][2] = 1 + settled = false + else + board[y][x] = {"bl", 0, x, y} + end + end + end + end + end + return settled +end + +resetBoard() + +local tileChar = { + { + "\131\148", + "\143\133", + }, + { + "10", + "00", + }, + { + "01", + "11", + } +} + +local to_blit = { + [0] = " ", + [colors.white] = "0", + [colors.orange] = "1", + [colors.magenta] = "2", + [colors.lightBlue] = "3", + [colors.yellow] = "4", + [colors.lime] = "5", + [colors.pink] = "6", + [colors.gray] = "7", + [colors.lightGray] = "8", + [colors.cyan] = "9", + [colors.purple] = "a", + [colors.blue] = "b", + [colors.brown] = "c", + [colors.green] = "d", + [colors.red] = "e", + [colors.black] = "f", +} + +term.setBackgroundColor(palette.bg) +term.clear() + +local checkIfWinner = function() + local conditions = {} + local winLength = 4 + + -- check horizontal + for y = 1, boardY do + for x = 1, boardX - winLength + 1 do + conditions[#conditions+1] = { + board[y][x+0], + board[y][x+1], + board[y][x+2], + board[y][x+3] + } + end + end + + -- check vertical + for y = 1, boardY - winLength + 1 do + for x = 1, boardX do + conditions[#conditions+1] = { + board[y+0][x], + board[y+1][x], + board[y+2][x], + board[y+3][x] + } + end + end + + -- check diagonals + for y = 1, boardY - winLength + 1 do + for x = 1, boardX - winLength + 1 do + conditions[#conditions+1] = { + board[y+3][x+0], + board[y+2][x+1], + board[y+1][x+2], + board[y+0][x+3] + } + conditions[#conditions+1] = { + board[y+0][x+0], + board[y+1][x+1], + board[y+2][x+2], + board[y+3][x+3] + } + end + end + + local winner, check + for set = 1, #conditions do + winner = true + check = conditions[set][1][1] + for piece = 2, #conditions[set] do + if conditions[set][piece][1] == "bl" or conditions[set][piece][1] ~= check then + winner = false + break + end + end + if winner then + return conditions[set][1][1], conditions[set] + end + end + return false +end + +local renderBoard = function() + local tileColRep = { + ["1"] = to_blit[palette.board] + } + local cx, cy + for y = 1, boardY + 1 do + if y == boardY + 1 then + term.setTextColor(palette.txt) + for x = 1, boardX do + term.setCursorPos(midX - (boardX) + (x - 1) * #tileChar[1][1], 4) + term.write(x) + end + cwrite("SPACE to clear", scr_y) + else + for ymod = 1, #tileChar[1] do + for x = 0, boardX do + cx = x * #tileChar[1][1] + (midX - boardX) - 2 + cy = y * #tileChar[1] + ymod + (midY - boardY) - 1 + if x == 0 then + term.setCursorPos(cx + 1, cy) + term.blit("\149", to_blit[palette.bg], to_blit[palette.board]) + else + term.setCursorPos(cx, cy) + if (board[y][x][2] == 0) or (board[y][x][2] == -1 and ymod == 1) or (board[y][x][2] == 1 and ymod == 2) then + tileColRep["0"] = to_blit[tiles[ board[y][x][1] ]] + elseif board[y][x][2] == 2 then + tileColRep["0"] = to_blit[palette.board] + else + tileColRep["0"] = to_blit[tiles["bl"]] + end + term.blit( + tileChar[1][ymod], + tileChar[2][ymod]:gsub(".", tileColRep), + tileChar[3][ymod]:gsub(".", tileColRep) + ) + end + end + end + end + end +end + +local getInput = function() + local evt + while true do + evt = {os.pullEvent()} + if evt[1] == "char" then + if tonumber(evt[2]) then + if tonumber(evt[2]) >= 1 and tonumber(evt[2]) <= boardX then + if not waiting then + addPiece(you, tonumber(evt[2])) + you, nou = nou, you + waiting = true + end + end + end + if evt[2] == " " then + os.queueEvent("clear_board") + for y = 1, boardY do + for x = 1, boardX do + board[y][x][2] = 0 + end + end + for x = 1, boardX do + block[x] = false + sleep(0.05) + end + you, nou = "P1", "P2" + sleep(1) + for x = 1, boardX do + block[x] = true + end + elseif evt[2] == "q" then + return "exit" + end + end + end +end + +local main = function() + local winner, winPieces + while true do + renderBoard() + while not moveTilesDown() do + sleep(sleepDelay) + renderBoard() + end + winner, winPieces = checkIfWinner() + term.setTextColor(palette.txt) + if winner then + term.setCursorPos(1,1) + term.clearLine() + cblit( + "Winner: " .. winner, + to_blit[palette.txt]:rep(8) .. to_blit[tiles[winner]]:rep(#winner), + to_blit[palette.bg]:rep(8 + #winner), + 1 + ) + parallel.waitForAny(function() + while true do + for p = 1, #winPieces do + board[winPieces[p][4]][winPieces[p][3]][2] = 0 + end + renderBoard() + sleep(0.3) + for p = 1, #winPieces do + board[winPieces[p][4]][winPieces[p][3]][2] = 2 + end + renderBoard() + sleep(0.2) + end + end, function() + local evt + repeat + evt = {os.pullEvent()} + until evt[1] == "clear_board" + end) + else + term.setCursorPos(1,1) + term.clearLine() + waiting = false + cblit( + "It's " .. you .. "'s turn.", + to_blit[palette.txt]:rep(5) .. to_blit[tiles[you]]:rep(#you) .. to_blit[palette.txt]:rep(8), + to_blit[palette.bg]:rep(13 + #you), + 1 + ) + end + sleep(sleepDelay) + end +end + +parallel.waitForAny(main, getInput) +cwrite("Thanks for playing!", 1) +term.setCursorPos(1, scr_y) +term.clearLine()