mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-05 20:40:25 -08:00
Merge pull request #932 from BrianWilkinsFL/main
Lua representation of flipflop game
This commit is contained in:
183
36_Flip_Flop/lua/flipflop-game.lua
Normal file
183
36_Flip_Flop/lua/flipflop-game.lua
Normal file
@@ -0,0 +1,183 @@
|
||||
--[[
|
||||
Game of FlipFlop
|
||||
===============
|
||||
|
||||
Based on the original BASIC game of FlipFlop from the 1970s.
|
||||
|
||||
This is a faithful recreation of the classic game, maintaining the original gameplay
|
||||
while modernizing the implementation for Lua. For example, the original's complex
|
||||
trigonometric random number generation has been replaced with Lua's math.random,
|
||||
as modern random number generators are more sophisticated than those available
|
||||
in 1970s BASIC.
|
||||
|
||||
How to Play:
|
||||
-----------
|
||||
The game presents a row of 10 X's. Your goal is to flip all X's to O's.
|
||||
Enter a number from 1-10 to flip that position. The computer will also make
|
||||
random moves in response. Special commands:
|
||||
- Enter 0 to see the current board again
|
||||
- Enter 11 to quit the game
|
||||
Try to complete the puzzle in 12 moves or fewer for the best score!
|
||||
|
||||
Strategy Tips:
|
||||
------------
|
||||
- When you make a move, watch how the computer responds. It will often
|
||||
make a predictable counter-move.
|
||||
- If you enter the same position twice, the computer will use a different
|
||||
random pattern for its response.
|
||||
- Try to work systematically from one end of the board to the other,
|
||||
rather than making random moves.
|
||||
- If you get stuck, sometimes starting over (11) is better than continuing
|
||||
with a poor position.
|
||||
|
||||
Technical Notes:
|
||||
--------------
|
||||
- Written for Lua 5.1 compatibility
|
||||
- Uses tables for game state management
|
||||
- Implements original game logic without goto statements
|
||||
- Preserves the original game's move counting and win conditions
|
||||
- Maintains the classic text-based interface style
|
||||
|
||||
Original BASIC Version:
|
||||
--------------------
|
||||
The original game used complex trigonometric functions for random number
|
||||
generation, likely due to limitations in BASIC's random number capabilities:
|
||||
R=TAN(Q+N/Q-N)-SIN(Q/N)+336*SIN(8*N)
|
||||
N=R-INT(R)
|
||||
N=INT(10*N)
|
||||
|
||||
This has been simplified to use Lua's built-in random number generator
|
||||
while maintaining the same gameplay experience.
|
||||
|
||||
Converted from BASIC to Lua by Brian Wilkins
|
||||
March 2025
|
||||
]]--
|
||||
|
||||
local function showInstructions()
|
||||
print(" FLIP FLOP")
|
||||
print(" CREATIVE COMPUTING")
|
||||
print(" MORRISTOWN, NEW JERSEY")
|
||||
print("\n\n")
|
||||
print("THE OBJECT OF THIS GAME IS TO FLIP ALL THE X'S TO O'S.")
|
||||
print("WHEN YOU INPUT A NUMBER, THAT NUMBER AND ALL ADJACENT")
|
||||
print("NUMBERS WILL BE FLIPPED.")
|
||||
print("\n")
|
||||
print("INPUT A NUMBER FROM 1 TO 10 TO START THE GAME. TO QUIT")
|
||||
print("THE GAME AT ANY TIME, TYPE A 0 (ZERO). TO START OVER WITH")
|
||||
print("A NEW PUZZLE IN THE MIDDLE OF A GAME, TYPE A 11 (ELEVEN).")
|
||||
print("\n\n")
|
||||
end
|
||||
|
||||
local function printUpdatedBoard(board)
|
||||
print("1 2 3 4 5 6 7 8 9 10")
|
||||
print(table.concat(board, " "))
|
||||
print("\n\n")
|
||||
end
|
||||
|
||||
local function processMove(gameState, position)
|
||||
-- Check if current position is O
|
||||
if gameState.board[position] == "O" then
|
||||
gameState.board[position] = "X"
|
||||
if position == gameState["lastMove"] then
|
||||
-- Generate random position using simplified random logic
|
||||
local R = math.random() -- between 0 and 1
|
||||
local N = math.floor(R * 10) + 1
|
||||
if gameState.board[N] == "O" then
|
||||
gameState.board[N] = "X"
|
||||
else
|
||||
gameState.board[N] = "O"
|
||||
end
|
||||
end
|
||||
else
|
||||
gameState.board[position] = "O"
|
||||
-- Generate another random position
|
||||
local R = math.random()
|
||||
local N = math.floor(R * 10) + 1
|
||||
if gameState.board[N] == "O" then
|
||||
gameState.board[N] = "X"
|
||||
else
|
||||
gameState.board[N] = "O"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function checkWin(gameState)
|
||||
-- Check if all positions are O's
|
||||
for i = 1, 10 do
|
||||
if gameState.board[i] ~= "O" then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function initializeGame()
|
||||
local gameState = {
|
||||
board = {},
|
||||
lastMove = nil,
|
||||
moves = 0
|
||||
}
|
||||
|
||||
-- Initialize board
|
||||
for i = 1, 10 do
|
||||
gameState.board[i] = "X"
|
||||
end
|
||||
return gameState
|
||||
end
|
||||
|
||||
local function playGame()
|
||||
showInstructions()
|
||||
|
||||
local gameState = initializeGame()
|
||||
local playing = true
|
||||
|
||||
print("HERE IS THE STARTING LINE OF X'S.")
|
||||
print("\n\n")
|
||||
printUpdatedBoard(gameState.board)
|
||||
|
||||
while playing do
|
||||
print("INPUT THE NUMBER")
|
||||
local N = tonumber(io.read())
|
||||
|
||||
-- Check if input is valid
|
||||
if not N or N ~= math.floor(N) then
|
||||
print("ILLEGAL ENTRY--TRY AGAIN.")
|
||||
elseif N == 11 then
|
||||
playing = false
|
||||
elseif N > 11 then
|
||||
print("ILLEGAL ENTRY--TRY AGAIN.")
|
||||
elseif N == 0 then
|
||||
printUpdatedBoard(gameState.board)
|
||||
else
|
||||
-- Process the move
|
||||
processMove(gameState, N)
|
||||
gameState["lastMove"] = N
|
||||
gameState.moves = gameState.moves + 1
|
||||
|
||||
-- Show the updated board
|
||||
printUpdatedBoard(gameState.board)
|
||||
|
||||
-- Check for win
|
||||
if checkWin(gameState) then
|
||||
if gameState.moves <= 12 then
|
||||
print(string.format("VERY GOOD. YOU GUESSED IT IN ONLY %d GUESSES.", gameState.moves))
|
||||
else
|
||||
print(string.format("TRY HARDER NEXT TIME. IT TOOK YOU %d GUESSES.", gameState.moves))
|
||||
end
|
||||
|
||||
print("DO YOU WANT TO TRY ANOTHER PUZZLE? (Y/N)")
|
||||
local answer = io.read():upper()
|
||||
if answer:sub(1,1) == "Y" then
|
||||
gameState = initializeGame()
|
||||
print("HERE IS THE STARTING LINE OF X'S.")
|
||||
print("\n\n")
|
||||
printUpdatedBoard(gameState.board)
|
||||
else
|
||||
playing = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
playGame()
|
||||
Reference in New Issue
Block a user