Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[Nim Learning Program: by QuantumGrav]]--
- --[[Preferences]]--
- local bColor, tColor, sTColor
- if term.isColor() then
- bColor = colors.lightGray
- tColor = colors.gray
- sTColor = colors.cyan
- end
- --[[Pre-Program]]--
- local w,h = term.getSize()
- w = w+1 -- Odd, but useful and neccessary for the GUI
- local selection = 1
- local menustate = "main" -- Both used for menu manipulation
- --[[Declarations]]--
- local moves = {}
- local movesMade = {}
- local movesMade1 = {}
- local max, number, turn, running, nHolder, mHolder, emphasis, str, ypos, result, times
- --[[Functions]]--
- local function printCentered(str, ypos) -- Draws str centered on ypos line
- term.setCursorPos(w/2-#str/2, ypos)
- term.write(str)
- end
- local function printRight(str, ypos) -- Draws str on the right on ypos line
- term.setCursorPos(w-#str, ypos)
- term.write(str)
- end
- local function drawHeadFoot() -- Draws the header and footer for the program
- if term.isColor() then
- term.setBackgroundColor(tColor)
- term.setTextColor(bColor)
- term.setCursorPos(1, 1)
- term.clearLine()
- term.setCursorPos(1, w)
- term.clearLine()
- end
- printCentered("Learning Intelligence: Nim", 1)
- printCentered(string.rep("-",w), 2) -- Draws the character "-" w (width of screen) times at line 2
- printCentered(string.rep("-",w), h-1) -- Draws the character "-" w (width of screen) times at h (height of screen) - 1
- term.setCursorPos(1,h)
- term.write("Version 1.0"..string.rep(" ",26))
- printRight("by QuantumGrav", h)
- if term.isColor() then
- term.setBackgroundColor(bColor)
- term.setTextColor(tColor)
- end
- end
- local function drawGUI() -- Draws the in game User Interface
- if term.isColor() then term.setBackgroundColor(bColor) end
- term.clear()
- drawHeadFoot()
- if term.isColor() then term.setTextColor(tColor) end
- printCentered("Max: "..max, 4)
- printCentered("Your Move: ", 13)
- if #movesMade ~= 0 then
- printCentered("Computer's Last Move: "..movesMade[#movesMade][3], 9)
- end
- printCentered("Remaining: ".. math.ceil(number), 5)
- if result ~= nil then
- printCentered(result, 15)
- printCentered("Press 'R' to play again or anything else to end.", 16)
- else
- printCentered("Type 'q' to Quit", 16)
- end
- end
- local function drawMain()
- drawHeadFoot()
- printCentered("> <", selection*5)
- for i=1, 3 do
- printCentered(mopt["main"].options[i], i*5)
- end
- end
- local function drawInfo()
- drawHeadFoot()
- printCentered("> Back <", 5)
- printCentered("Learning Intelligence: Nim", 7)
- printCentered("by QuantumGrav", 8)
- printCentered("The goal of the game is to force your", 10)
- printCentered("opponent to take the final piece.", 11)
- printCentered("The maximum that can be taken, the starting", 13)
- printCentered("number, and the first move of the game", 14)
- printCentered("are all user determined.", 15)
- printCentered("Enjoy!", 17)
- end
- mopt = {
- ["main"] = {
- options = {"Play", "Info", "Quit"},
- draw = drawMain
- },
- ["Info"] = {
- options = {"main"},
- draw = drawInfo
- }
- }
- local function runMenu()
- if term.isColor() then term.setBackgroundColor(bColor) end
- local menuResult = {}
- while true do
- term.clear()
- menuResult = {}
- mopt[menustate].draw()
- local event, id, x, y = os.pullEvent()
- if event == "mouse_click" then
- if x <= w/2+2 and x >= w/2-2 then
- if y==5 then
- if selection == 1 then
- if mopt[menustate].options[selection] == "Play" then
- menuResult = "Play"
- break
- else
- menustate = mopt[menustate].options[selection]
- selection = 1
- end
- else
- selection = 1
- end
- elseif y==10 then
- if selection == 2 then menustate = mopt[menustate].options[selection] selection = 1 else selection = 2 end
- elseif y==15 then
- if selection == 3 then
- if mopt[menustate].options[selection] == "Quit" then
- menuResult = "Quit"
- break
- else
- menustate = mopt[menustate].options[selection]
- selection = 1
- end
- else
- selection = 3
- end
- end
- end
- elseif event == "key" then
- if id == 200 and selection > 1 then selection = selection - 1
- elseif id == 208 and selection < #mopt[menustate].options then selection = selection + 1
- elseif id == 28 then
- if mopt[menustate].options[selection] == "Quit" or mopt[menustate].options[selection] == "Play" then
- menuResult = mopt[menustate].options[selection]
- break
- else
- menustate = mopt[menustate].options[selection]
- selection = 1
- end
- end
- end
- end
- return menuResult
- end
- local function save(table,name)
- local file = fs.open(name,"w")
- file.write(textutils.serialize(table))
- file.close()
- end
- local function load(name)
- local file = fs.open(name,"r")
- local data = file.readAll()
- file.close()
- return textutils.unserialize(data)
- end
- local function prompt()
- while true do
- term.clear()
- drawHeadFoot()
- printCentered("Would you me to improve my game? (y/n) : ", 5)
- imp = io.read()
- if imp == "y" or imp == "n" then break end
- end
- while true do
- term.clear()
- drawHeadFoot()
- printCentered("Maximum that can be taken: (Max 10) : ", 5)
- max = io.read()
- if tonumber(max) then
- max = tonumber(max)
- if max > 0 and max <= 10 then break end
- end
- end
- while true do
- term.clear()
- drawHeadFoot()
- printCentered("Size of pile to begin: (Max 100) : ", 5)
- number = io.read()
- if tonumber(number) then
- number = tonumber(number)
- if number > 0 and number <= 100 then break end
- end
- end
- if imp == "n" then
- while true do
- term.clear()
- drawHeadFoot()
- printCentered("Would you like to go first? (y/n) : ", 5)
- turn = io.read()
- if turn == "y" or turn == "n" then break end
- end
- else
- while true do
- term.clear()
- drawHeadFoot()
- printCentered("How many times? (Max 100) : ", 5)
- impN = io.read()
- if tonumber(impN) then
- impN = tonumber(impN)
- if impN > 0 and impN <= 100 then break end
- end
- end
- end
- end
- local function getHistory()
- if fs.exists("NimHistory") then
- moves = load("NimHistory")
- end
- end
- local function compMove(value)
- if moves[max] == nil then moves[max] = {} end
- if moves[max][number] == nil then moves[max][number] = {} end
- for i=1,max do
- if moves[max][number][i] == nil then moves[max][number][i] = 0 end
- end
- for k,v in pairs(moves[max][number]) do
- if k == 1 and k <= number then nHolder = v mHolder = k end
- if v > nHolder and k <= number then nHolder = v mHolder = k end
- end
- if value == true then movesMade[#movesMade+1] = {max, number, mHolder} else movesMade1[#movesMade1+1] = {max, number, mHolder} end
- number = number-mHolder
- end
- local function playerMove()
- while true do
- drawGUI()
- term.setCursorPos(w/2+5 ,13)
- mHolder = io.read()
- if mHolder == "q" then break end
- if tonumber(mHolder) then
- mHolder = tonumber(mHolder)
- if mHolder > 0 and mHolder <= number and mHolder <= max then
- number = number - mHolder
- break
- end
- end
- end
- end
- local function improve(maxN, numberN, timesN)
- for i=1, timesN do
- movesMade = {}
- movesMade1 = {}
- max = maxN
- number = numberN
- getHistory()
- while true do
- if number == 0 then result = "You Have Won!" break end
- compMove(true)
- if number == 0 then result = "You Have Lost!" break end
- compMove(false)
- end
- emphasis = 0
- if result == "You have Lost!" then emphasis = 1 elseif result == "You Have Won!" then emphasis = -1 end
- if emphasis == 0 then emphasis = 1 end
- for i=1,#movesMade do
- if moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] == nil then moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] = 0 end
- moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] = moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] - emphasis
- end
- for i=1,#movesMade1 do
- if moves[movesMade1[i][1]][movesMade1[i][2]][movesMade1[i][3]] == nil then moves[movesMade1[i][1]][movesMade1[i][2]][movesMade1[i][3]] = 0 end
- moves[movesMade1[i][1]][movesMade1[i][2]][movesMade1[i][3]] = moves[movesMade1[i][1]][movesMade1[i][2]][movesMade1[i][3]] + emphasis
- fs.delete("NimHistory")
- save(moves, "NimHistory")
- end
- sleep(0)
- end
- end
- --[[Main]]--
- local function main()
- a = runMenu()
- if a ~= "Quit" then
- prompt()
- if imp == "n" then
- getHistory()
- if turn == "n" then compMove() end
- while true do
- if number == 0 then result = "You Have Won!" break end
- playerMove()
- if number == 0 or mHolder == "q" then result = "You Have Lost!" break end
- compMove()
- end
- if mHolder ~= "q" then
- drawGUI()
- emphasis = 0
- if result == "You have Lost!" then emphasis = 1 elseif result == "You Have Won!" then emphasis = -1 end
- if emphasis == 0 then emphasis = 1 end
- for i=1,#movesMade do
- if moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] == nil then moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] = 0 end
- moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] = moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] + emphasis
- end
- fs.delete("NimHistory")
- save(moves, "NimHistory")
- event, id = os.pullEvent("key")
- end
- else
- term.clear()
- drawHeadFoot()
- printCentered("This may take some time.", 5)
- improve(max, number, impN)
- term.clear()
- drawHeadFoot()
- printCentered("Finished!", 5)
- sleep(1)
- id = keys.r
- end
- end
- if id ~= keys.r and a ~= "Quit" then
- term.clear()
- term.setCursorPos(w/2-9, h/2)
- textutils.slowPrint("Thanks for Playing!")
- sleep(1.5)
- end
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.clear()
- term.setCursorPos(1,1)
- if id == keys.r then movesMade = {} result = nil id = nil main() end
- end
- main()
- --improve(3, 10, 100)
Add Comment
Please, Sign In to add comment