Guest User

Learning Intelligence: Nim QuantumGrav

a guest
Apr 29th, 2013
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[Nim Learning Program: by QuantumGrav]]--
  2.  
  3. --[[Preferences]]--
  4.  
  5. local bColor, tColor, sTColor
  6.  
  7. if term.isColor() then
  8. bColor = colors.lightGray
  9. tColor = colors.gray
  10. sTColor = colors.cyan
  11. end
  12.  
  13. --[[Pre-Program]]--
  14.  
  15. local w,h = term.getSize()
  16. w = w+1 -- Odd, but useful and neccessary for the GUI
  17. local selection = 1
  18. local menustate = "main" -- Both used for menu manipulation
  19.  
  20. --[[Declarations]]--
  21.  
  22. local moves = {}
  23. local movesMade = {}
  24. local movesMade1 = {}
  25. local max, number, turn, running, nHolder, mHolder, emphasis, str, ypos, result, times
  26.  
  27. --[[Functions]]--
  28.  
  29. local function printCentered(str, ypos) -- Draws str centered on ypos line
  30. term.setCursorPos(w/2-#str/2, ypos)
  31. term.write(str)
  32. end
  33.  
  34. local function printRight(str, ypos) -- Draws str on the right on ypos line
  35. term.setCursorPos(w-#str, ypos)
  36. term.write(str)
  37. end
  38.  
  39. local function drawHeadFoot() -- Draws the header and footer for the program
  40. if term.isColor() then
  41. term.setBackgroundColor(tColor)
  42. term.setTextColor(bColor)
  43. term.setCursorPos(1, 1)
  44. term.clearLine()
  45. term.setCursorPos(1, w)
  46. term.clearLine()
  47. end
  48. printCentered("Learning Intelligence: Nim", 1)
  49. printCentered(string.rep("-",w), 2) -- Draws the character "-" w (width of screen) times at line 2
  50. printCentered(string.rep("-",w), h-1) -- Draws the character "-" w (width of screen) times at h (height of screen) - 1
  51. term.setCursorPos(1,h)
  52. term.write("Version 1.0"..string.rep(" ",26))
  53. printRight("by QuantumGrav", h)
  54. if term.isColor() then
  55. term.setBackgroundColor(bColor)
  56. term.setTextColor(tColor)
  57. end
  58. end
  59.  
  60. local function drawGUI() -- Draws the in game User Interface
  61. if term.isColor() then term.setBackgroundColor(bColor) end
  62. term.clear()
  63. drawHeadFoot()
  64. if term.isColor() then term.setTextColor(tColor) end
  65. printCentered("Max: "..max, 4)
  66. printCentered("Your Move: ", 13)
  67. if #movesMade ~= 0 then
  68. printCentered("Computer's Last Move: "..movesMade[#movesMade][3], 9)
  69. end
  70. printCentered("Remaining: ".. math.ceil(number), 5)
  71. if result ~= nil then
  72. printCentered(result, 15)
  73. printCentered("Press 'R' to play again or anything else to end.", 16)
  74. else
  75. printCentered("Type 'q' to Quit", 16)
  76. end
  77. end
  78.  
  79. local function drawMain()
  80. drawHeadFoot()
  81. printCentered("> <", selection*5)
  82. for i=1, 3 do
  83. printCentered(mopt["main"].options[i], i*5)
  84. end
  85. end
  86.  
  87. local function drawInfo()
  88. drawHeadFoot()
  89. printCentered("> Back <", 5)
  90. printCentered("Learning Intelligence: Nim", 7)
  91. printCentered("by QuantumGrav", 8)
  92. printCentered("The goal of the game is to force your", 10)
  93. printCentered("opponent to take the final piece.", 11)
  94. printCentered("The maximum that can be taken, the starting", 13)
  95. printCentered("number, and the first move of the game", 14)
  96. printCentered("are all user determined.", 15)
  97. printCentered("Enjoy!", 17)
  98. end
  99.  
  100. mopt = {
  101. ["main"] = {
  102. options = {"Play", "Info", "Quit"},
  103. draw = drawMain
  104. },
  105. ["Info"] = {
  106. options = {"main"},
  107. draw = drawInfo
  108. }
  109. }
  110.  
  111. local function runMenu()
  112. if term.isColor() then term.setBackgroundColor(bColor) end
  113. local menuResult = {}
  114. while true do
  115. term.clear()
  116. menuResult = {}
  117. mopt[menustate].draw()
  118. local event, id, x, y = os.pullEvent()
  119. if event == "mouse_click" then
  120. if x <= w/2+2 and x >= w/2-2 then
  121. if y==5 then
  122. if selection == 1 then
  123. if mopt[menustate].options[selection] == "Play" then
  124. menuResult = "Play"
  125. break
  126. else
  127. menustate = mopt[menustate].options[selection]
  128. selection = 1
  129. end
  130. else
  131. selection = 1
  132. end
  133. elseif y==10 then
  134. if selection == 2 then menustate = mopt[menustate].options[selection] selection = 1 else selection = 2 end
  135. elseif y==15 then
  136. if selection == 3 then
  137. if mopt[menustate].options[selection] == "Quit" then
  138. menuResult = "Quit"
  139. break
  140. else
  141. menustate = mopt[menustate].options[selection]
  142. selection = 1
  143. end
  144. else
  145. selection = 3
  146. end
  147. end
  148. end
  149. elseif event == "key" then
  150. if id == 200 and selection > 1 then selection = selection - 1
  151. elseif id == 208 and selection < #mopt[menustate].options then selection = selection + 1
  152. elseif id == 28 then
  153. if mopt[menustate].options[selection] == "Quit" or mopt[menustate].options[selection] == "Play" then
  154. menuResult = mopt[menustate].options[selection]
  155. break
  156. else
  157. menustate = mopt[menustate].options[selection]
  158. selection = 1
  159. end
  160. end
  161. end
  162. end
  163. return menuResult
  164. end
  165.  
  166. local function save(table,name)
  167. local file = fs.open(name,"w")
  168. file.write(textutils.serialize(table))
  169. file.close()
  170. end
  171.  
  172. local function load(name)
  173. local file = fs.open(name,"r")
  174. local data = file.readAll()
  175. file.close()
  176. return textutils.unserialize(data)
  177. end
  178.  
  179. local function prompt()
  180. while true do
  181. term.clear()
  182. drawHeadFoot()
  183. printCentered("Would you me to improve my game? (y/n) : ", 5)
  184. imp = io.read()
  185. if imp == "y" or imp == "n" then break end
  186. end
  187. while true do
  188. term.clear()
  189. drawHeadFoot()
  190. printCentered("Maximum that can be taken: (Max 10) : ", 5)
  191. max = io.read()
  192. if tonumber(max) then
  193. max = tonumber(max)
  194. if max > 0 and max <= 10 then break end
  195. end
  196. end
  197. while true do
  198. term.clear()
  199. drawHeadFoot()
  200. printCentered("Size of pile to begin: (Max 100) : ", 5)
  201. number = io.read()
  202. if tonumber(number) then
  203. number = tonumber(number)
  204. if number > 0 and number <= 100 then break end
  205. end
  206. end
  207. if imp == "n" then
  208. while true do
  209. term.clear()
  210. drawHeadFoot()
  211. printCentered("Would you like to go first? (y/n) : ", 5)
  212. turn = io.read()
  213. if turn == "y" or turn == "n" then break end
  214. end
  215. else
  216. while true do
  217. term.clear()
  218. drawHeadFoot()
  219. printCentered("How many times? (Max 100) : ", 5)
  220. impN = io.read()
  221. if tonumber(impN) then
  222. impN = tonumber(impN)
  223. if impN > 0 and impN <= 100 then break end
  224. end
  225. end
  226. end
  227. end
  228.  
  229. local function getHistory()
  230. if fs.exists("NimHistory") then
  231. moves = load("NimHistory")
  232. end
  233. end
  234.  
  235. local function compMove(value)
  236. if moves[max] == nil then moves[max] = {} end
  237. if moves[max][number] == nil then moves[max][number] = {} end
  238. for i=1,max do
  239. if moves[max][number][i] == nil then moves[max][number][i] = 0 end
  240. end
  241. for k,v in pairs(moves[max][number]) do
  242. if k == 1 and k <= number then nHolder = v mHolder = k end
  243. if v > nHolder and k <= number then nHolder = v mHolder = k end
  244. end
  245. if value == true then movesMade[#movesMade+1] = {max, number, mHolder} else movesMade1[#movesMade1+1] = {max, number, mHolder} end
  246. number = number-mHolder
  247. end
  248.  
  249. local function playerMove()
  250. while true do
  251. drawGUI()
  252. term.setCursorPos(w/2+5 ,13)
  253. mHolder = io.read()
  254. if mHolder == "q" then break end
  255. if tonumber(mHolder) then
  256. mHolder = tonumber(mHolder)
  257. if mHolder > 0 and mHolder <= number and mHolder <= max then
  258. number = number - mHolder
  259. break
  260. end
  261. end
  262. end
  263. end
  264.  
  265. local function improve(maxN, numberN, timesN)
  266. for i=1, timesN do
  267. movesMade = {}
  268. movesMade1 = {}
  269. max = maxN
  270. number = numberN
  271. getHistory()
  272. while true do
  273. if number == 0 then result = "You Have Won!" break end
  274. compMove(true)
  275. if number == 0 then result = "You Have Lost!" break end
  276. compMove(false)
  277. end
  278. emphasis = 0
  279. if result == "You have Lost!" then emphasis = 1 elseif result == "You Have Won!" then emphasis = -1 end
  280. if emphasis == 0 then emphasis = 1 end
  281. for i=1,#movesMade do
  282. 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
  283. moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] = moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] - emphasis
  284. end
  285. for i=1,#movesMade1 do
  286. 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
  287. moves[movesMade1[i][1]][movesMade1[i][2]][movesMade1[i][3]] = moves[movesMade1[i][1]][movesMade1[i][2]][movesMade1[i][3]] + emphasis
  288. fs.delete("NimHistory")
  289. save(moves, "NimHistory")
  290. end
  291. sleep(0)
  292. end
  293. end
  294.  
  295. --[[Main]]--
  296.  
  297. local function main()
  298. a = runMenu()
  299. if a ~= "Quit" then
  300. prompt()
  301. if imp == "n" then
  302. getHistory()
  303. if turn == "n" then compMove() end
  304. while true do
  305. if number == 0 then result = "You Have Won!" break end
  306. playerMove()
  307. if number == 0 or mHolder == "q" then result = "You Have Lost!" break end
  308. compMove()
  309. end
  310. if mHolder ~= "q" then
  311. drawGUI()
  312. emphasis = 0
  313. if result == "You have Lost!" then emphasis = 1 elseif result == "You Have Won!" then emphasis = -1 end
  314. if emphasis == 0 then emphasis = 1 end
  315. for i=1,#movesMade do
  316. 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
  317. moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] = moves[movesMade[i][1]][movesMade[i][2]][movesMade[i][3]] + emphasis
  318. end
  319. fs.delete("NimHistory")
  320. save(moves, "NimHistory")
  321. event, id = os.pullEvent("key")
  322. end
  323. else
  324. term.clear()
  325. drawHeadFoot()
  326. printCentered("This may take some time.", 5)
  327. improve(max, number, impN)
  328. term.clear()
  329. drawHeadFoot()
  330. printCentered("Finished!", 5)
  331. sleep(1)
  332. id = keys.r
  333. end
  334. end
  335. if id ~= keys.r and a ~= "Quit" then
  336. term.clear()
  337. term.setCursorPos(w/2-9, h/2)
  338. textutils.slowPrint("Thanks for Playing!")
  339. sleep(1.5)
  340. end
  341. term.setBackgroundColor(colors.black)
  342. term.setTextColor(colors.white)
  343. term.clear()
  344. term.setCursorPos(1,1)
  345. if id == keys.r then movesMade = {} result = nil id = nil main() end
  346. end
  347.  
  348. main()
  349. --improve(3, 10, 100)
Add Comment
Please, Sign In to add comment