Advertisement
Guest User

Untitled

a guest
Mar 26th, 2020
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.04 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # Import aus Library
  3. import os
  4. import sys
  5. import time
  6. from ev3dev2.sensor.lego import TouchSensor, ColorSensor
  7. from ev3dev2.sensor import INPUT_1, INPUT_4, INPUT_3
  8. from ev3dev2.sound import Sound
  9. from ev3dev2.led import Leds
  10. from ev3dev2.button import Button
  11. from random import randrange
  12. from math import inf
  13. from ev3dev2.motor import LargeMotor, MediumMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent, MoveTank
  14.  
  15. #region Hintergrund-Einstellungen (notwendig für Kompatibilität)
  16. def debug_print(*args, **kwargs):
  17. print(*args, **kwargs, file=sys.stderr)
  18.  
  19. btn = Button()
  20. leds = Leds()
  21. sound = Sound()
  22. ON = True
  23. OFF = False
  24.  
  25. #
  26. def reset_console():
  27. print('\x1Bc', end='')
  28.  
  29.  
  30. def set_cursor(state):
  31. if state:
  32. print('\x1B[?25h', end='')
  33. else:
  34. print('\x1B[?25l', end='')
  35.  
  36.  
  37. def set_font(name):
  38. os.system('setfont ' + name)
  39. #endregion
  40.  
  41. def rockpaperscissors(): # Funktion für Schere, Stein, Papier
  42. # Globale Variablen
  43. global starter
  44.  
  45. rpsResult = 0 # Ergebnis von Schere, Stein, Papier
  46. rpsAI = 0 # SSP-Auswahl des Computers
  47.  
  48. leds.set_color("LEFT", "AMBER")
  49. leds.set_color("RIGHT", "AMBER")
  50. time.sleep(1)
  51. sound.speak('Please use the right, left or down button to select either rock, paper or scissors.')
  52. sound.speak('The left button will result in rock, the down button will result in paper and the right button will result in scissors.')
  53. sound.speak('Then use the center button to confirm your choice.')
  54.  
  55. while rpsResult == 0: # Solange kein Ergebnis erreicht wurde, wiederholt sich die Schleife
  56. if btn.left:
  57. rps = 1 # Auswahl wird auf Stein gesetzt
  58. leds.set_color("LEFT", "ORANGE")
  59. leds.set_color("RIGHT", "BLACK")
  60. sound.speak('Rock is now selected.')
  61. elif btn.down:
  62. rps = 2 # Auswahl wird auf Papier gesetzt
  63. leds.set_color("LEFT", "ORANGE")
  64. leds.set_color("RIGHT", "ORANGE")
  65. sound.speak('Paper is now selected.')
  66. elif btn.right:
  67. rps = 3 # Auswahl wird auf Schere gesetzt
  68. leds.set_color("RIGHT", "ORANGE")
  69. leds.set_color("LEFT", "BLACK")
  70. sound.speak('Scissors is now selected.')
  71. elif btn.enter:
  72. if rps == 0: # Wenn der Spieler sich noch nicht entschieden hat, muss er nochmal bestätigen
  73. sound.speak('Please select either rock, paper or scissors first.')
  74. else:
  75. rpsAI = randrange(2) + 1 # Berechnung der Computer-Auswahl
  76.  
  77. if rps == rpsAI: # Wenn der Spieler und der Computer das gleiche gewählt haben, muss nochmal gespielt werden
  78. if rps == 1:
  79. sound.speak("You both chose rock. Please play again.")
  80. elif rps == 2:
  81. sound.speak("You both chose paper. Please play again.")
  82. elif rps == 3:
  83. sound.speak("You both chose scissors. Please play again.")
  84. elif rps == 1: # Wenn der Spieler Stein wählt..
  85. if rpsAI == 2: # ..und der Computer Papier,..
  86. rpsResult = 2 # ..dann gewinnt der Computer
  87. elif rpsAI == 3: # ..und der Computer Schere,..
  88. rpsResult = 1 # ..dann gewinnt der Spieler
  89. elif rps == 2: # Wenn der Spieler Papier wählt..
  90. if rpsAI == 1: # ..und der Computer Stein,..
  91. rpsResult = 1 # ..dann gewinnt der Spieler
  92. elif rpsAI == 3: # ..und der Computer Schere,..
  93. rpsResult = 2 # ..dann gewinnt der Computer
  94. elif rps == 3: # Wenn der Spieler Schere wählt..
  95. if rpsAI == 1: # ..und der Computer Stein,..
  96. rpsResult = 2 # ..dann gewinnt der Computer
  97. elif rpsAI == 2: # ..und der Computer Papier,..
  98. rpsResult = 1 # ..dann gewinnt der Spieler
  99.  
  100. if rpsResult == 1: # Wenn der Spieler gewinnt, wird der Start-Wert auf Spieler (1) gesetzt und Tic-Tac-Toe gestartet
  101. leds.set_color("RIGHT", "GREEN")
  102. leds.set_color("LEFT", "GREEN")
  103. sound.speak("Congratulations! You won this time and you may now start.")
  104. starter = 1
  105. tictactoe()
  106. elif rpsResult == 2: # Wenn der Computer gewinnt, wird der Start-Wert auf Computer (0) gesetzt und Tic-Tac-Toe gestartet
  107. leds.set_color("LEFT", "RED")
  108. leds.set_color("RIGHT", "RED")
  109. sound.speak("You unfortunately lost. The computer will start.")
  110. starter = 0
  111. tictactoe()
  112.  
  113. def main():
  114. # Einrichtung zur Kompatibilität
  115. reset_console()
  116. set_cursor(OFF)
  117. set_font('Lat15-Terminus24x12')
  118.  
  119. # Globale Variablen
  120. global pen
  121. global xMax
  122. global yMax
  123. global xPos
  124. global yPos
  125. global fields
  126.  
  127. fields = [0, 0, 0, 0, 0, 0, 0, 0, 0] # Array, welches Feld von welchem Spieler bemalt ist
  128. xPos = 0 # x-Position des Stiftes
  129. yPos = 0 # y-Position des Stiftes
  130. xMax = 300 # Maximaler x-Wert des Feldes
  131. yMax = 220 # Maxmimaler y-Wert des Feldes
  132. pen = 1 # Position des Stiftes
  133.  
  134. leds.all_off()
  135. time.sleep(1)
  136. leds.set_color("LEFT", "RED")
  137. leds.set_color("RIGHT", "RED")
  138. time.sleep(1)
  139.  
  140. sound.speak('Welcome to Tic Tac Toe by Johannes Peters and Niels Hannemann.')
  141. sound.speak('Press the right button for a slow start with rock, papers and scissors.')
  142. sound.speak('Press the middle button for a quick start.')
  143. time.sleep(1)
  144. leds.set_color("LEFT", "AMBER")
  145. leds.set_color("RIGHT", "AMBER")
  146.  
  147. while True:
  148. if btn.enter: # Wenn der Spieler den Schnellstart wählt. wird ein zufälliger Starter ausgewählt
  149. starter = randrange(0, 2) + 1
  150. tictactoe()
  151. elif btn.right: # Wenn der Spieler Schere, Stein, Papier wählt, wird die Funktion aufgerufen
  152. rockpaperscissors()
  153.  
  154. def pendown(): # Funktion zur Bewegung des Stiftes in die untere Position
  155. # Globale Variablen
  156. global pen
  157.  
  158. m = MediumMotor(OUTPUT_C) # Initialisierung des Motors
  159. if pen == 0: # Checken, ob der Stift bereits in der unteren Position ist - wenn dem so ist, wird der Stift nicht weiter bewegt
  160. return
  161. m.on_for_rotations(SpeedPercent(-10), 0.086)
  162. pen = 0 # Stift-Position wird nach unten versetzt
  163.  
  164. def penup(): # Funktion zur Bewegung des Stiftes in die obere Position
  165. # Globale Variablen
  166. global pen
  167.  
  168. m = MediumMotor(OUTPUT_C) # Initialisierung des Motors
  169. if pen == 1: # Checken, ob der Stift bereits in der oberen Position ist - wenn dem so ist, wird der Stift nicht weiter bewegt
  170. return
  171. m.on_for_rotations(SpeedPercent(10), 0.086)
  172. pen = 1 # Stift-Position wird nach unten versetzt
  173.  
  174. def drawGame(): # Funktion zum Zeichnen des Spielfelds
  175. # Globale Variablen
  176. global xMax
  177. global yMax
  178. # Abmessungen des Spielfelds, jeweils Linien auf 1/3 und 2/3 der gesamten Länge bzw. Breite
  179. draw((1/3) * xMax, 0, (1/3) * xMax, yMax, False)
  180. draw((2/3) * xMax, 0, (2/3) * xMax, yMax, False)
  181. draw(0, (1/3) * yMax, xMax, (1/3) * yMax, False)
  182. draw(0, (2/3) * yMax, xMax, (2/3) * yMax, False)
  183.  
  184. def resetMov(): # Funktion zum Zurücksetzen des Scan & Zeichenblocks mit Motor an Port C (x-Richtung)
  185. ts = TouchSensor(INPUT_1) # Initialisierung des Drucksensors
  186. m = MediumMotor(OUTPUT_C) # Initialisierung des Motors
  187.  
  188. while not ts.is_pressed: # Block wird solange in x-Richtung bewegt, bis Drucksensor durch den Block gedrückt worden ist
  189. xMot = LargeMotor(OUTPUT_D) # Initialisierung des Motors
  190. xMot.on(30, 30)
  191. if ts.is_pressed:
  192. xMot.stop()
  193. penup() # Stift wird in die obere Position bewegt
  194. xPos = 0 # x-Position wird angepasst/zurückgesetzt
  195.  
  196. def drawX(): # Funktion zum Zeichnen des CPU-Symbols auf dem Spielfeld
  197. # Globale Variablen
  198. global xPos
  199. global yPos
  200. global activeField
  201. global fields
  202.  
  203. ancleX = xPos # Ankerpunkt-Variable
  204. ancleY = yPos # Ankerpunkt-Variable
  205. width = 25 # Größe des Symbols
  206.  
  207. # Das Symbol wird gezeichnet
  208. move(ancleX - width, ancleY - width, False)
  209. pendown()
  210. move(ancleX + width, ancleY - width, False)
  211. move(ancleX + width, ancleY + width, False)
  212. move(ancleX - width, ancleY + width, False)
  213. move(ancleX - width, ancleY - width, False)
  214. penup()
  215.  
  216. fields[activeField] = 1 # Spieler-Zug wird in das Array eingetragen
  217.  
  218. def moveToField(i): # Funktion zur Bewegung zum ausgewählten Feld
  219. # Globale Variablen
  220. global xMax
  221. global yMax
  222. global activeField
  223.  
  224. if i == 6: #Feld unten links
  225. move((1/6) * xMax, (1/6) * yMax, False)
  226. activeField = i
  227. elif i == 7: #Feld unten mittig
  228. move(0.5 * xMax, (1/6) * yMax, False)
  229. activeField = i
  230. elif i == 8: #Feld unten rechts
  231. move((5/6) * xMax + 15, (1/6) * yMax, False)
  232. activeField = i
  233. elif i == 3: #Feld mittig links
  234. move((1/6) * xMax, 0.5 * yMax - 5, False)
  235. activeField = i
  236. elif i == 4: #Feld Mitte
  237. move(0.5 * xMax, 0.5 * yMax - 5, False)
  238. activeField = i
  239. elif i == 5: #Feld mittig rechts
  240. move((5/6) * xMax, 0.5 * yMax - 5, False)
  241. activeField = i
  242. elif i == 0: #Feld oben links
  243. move((1/6) * xMax, (5/6) * yMax, False)
  244. activeField = i
  245. elif i == 1: #Feld oben mittig
  246. move(0.5 * xMax, (5/6) * yMax, False)
  247. activeField = i
  248. elif i == 2: #Feld oben rechts
  249. move((5/6) * xMax, (5/6) * yMax, False)
  250. activeField = i
  251.  
  252. def checkField(i): #Funktion zum Auszesen, ob und wo der Spieler sein "Kreuz" gesetzt hat
  253. global xPos
  254. global yPos
  255. global fields
  256. global change
  257.  
  258. moveToField(i) #Bewegung zum Feld
  259. cs = ColorSensor(INPUT_4) #Input des Farbsensors
  260. move(xPos + 32, yPos - 40, False) #Leichte Positionsänderung, damit der Farbsensor optimal zum Auslesen platziert ist
  261. if i == 0 or i == 1 or i == 2: #Weitere Positionsänderungen für einzelne Felder (obere Reihe und das rechte untere Feld)
  262. move(xPos, yPos - 7, False)
  263. elif i == 8:
  264. move(xPos - 5, yPos, False)
  265.  
  266. if not (cs.color == 6 or cs.color == 0): #Wenn die erkannte Farbe nicht weiß oder unerkannt ist,
  267. fields[i] = 2 #wird das Feld in der Liste als vom Spieler bespielt gesetzt (0 -> unbesetzt, 1 -> CPU, 2 -> Spieler) und
  268. change += 1 #die "change"-Variable um 1 erhöht, sodass die CPU kontrollieren kann, dass nur genau ein Feld verändert wurde
  269. if change == 1:
  270. sound.speak('Good move!')
  271. elif not change == 1:
  272. sound.speak('Wait a second!')
  273.  
  274. def checkFields():
  275. global fieldsToCheck
  276. global noFieldsLeft
  277. global fieldsLeft
  278. fieldsLeft = 0
  279.  
  280. fieldsToCheck = ["0", "0", "0", "0", "0", "0", "0", "0", "0"]
  281. noFieldsLeft = True
  282. n = 8
  283. s = 0
  284. m = 0
  285. change = 0
  286.  
  287. for counter in range(0, n + 1):
  288. if fields[s] == 0:
  289. checkField(s)
  290. if fields[s] == 0:
  291. fieldsToCheck[m] = s
  292. fieldsLeft += 1
  293. noFieldsLeft = False
  294. m += 1
  295. s += 1
  296.  
  297. def draw(x, y, x2, y2, dia): #Funktion zum Malen von gegebenen Strecken (von Koordinaten x, y zu neuen Koordinaten x2, y2; schräg oder nicht schräg gezeichnet)
  298. penup()
  299. move(x, y, False)
  300. time.sleep(0.3)
  301. pendown()
  302. time.sleep(0.5)
  303. move(x2, y2, dia)
  304. penup()
  305.  
  306. def rollOut(): #Funktion zum Herausrollen des Papiers
  307. global xPos
  308. global yPos
  309.  
  310. move(xPos, 380, False)
  311.  
  312. def move(x, y, dia):
  313. global xPos
  314. global yPos
  315.  
  316. xMov = x - xPos
  317. yMov = y - yPos
  318.  
  319. xMot = LargeMotor(OUTPUT_D)
  320. yMot = LargeMotor(OUTPUT_A)
  321. tank_drive = MoveTank(OUTPUT_D, OUTPUT_A)
  322.  
  323. if dia == True:
  324. tank_drive.on_for_degrees(SpeedPercent(-30), SpeedPercent(30), xMov, yMov)
  325. else:
  326. xMot.on_for_degrees(SpeedPercent(-15), xMov)
  327. yMot.on_for_degrees(SpeedPercent(15), yMov)
  328.  
  329. xPos += xMov
  330. yPos += yMov
  331.  
  332. def CPUTurn():
  333. global turn
  334. global idleCancel
  335. global fieldsLeft
  336. global fieldsToCheck
  337. idleCancel = False
  338.  
  339. moveToField(testforbestfield(0, -1))
  340. #moveToField(fieldsToCheck[randrange(0, fieldsLeft + 1)])
  341. drawX()
  342.  
  343. def humanTurn():
  344. global change
  345. global idleCancel
  346. change = 0
  347. idleCancel = False
  348. ts = TouchSensor(INPUT_3)
  349.  
  350. while change == 0:
  351. rollOut()
  352.  
  353. sound.speak('Your turn!')
  354. while not ts.is_pressed:
  355. time.sleep(0.0001)
  356. checkFields()
  357. if change == 0:
  358. sound.speak('Sorry, I could not recognize your move. Please try again!')
  359.  
  360. if change >= 2:
  361. sound.speak('Please only do one move at a time. The game will be disrupted.')
  362. idleCancel = True
  363.  
  364. def replay():
  365. ts = TouchSensor(INPUT_3)
  366. sound.speak('Press the enter button to quickplay again!')
  367. sound.speak('Press the right button to play with rock, papers and scissors.')
  368.  
  369. while not ts.is_pressed:
  370. sound.speak('Please put in another blank paper!')
  371. move(0, 0, False)
  372. while not btn.any():
  373. if btn.enter:
  374. tictactoe()
  375. elif btn.right:
  376. rockpaperscissors()
  377.  
  378. def testforbestfield(n, player):
  379. global fields
  380. testingField = 0
  381. fieldsBackup = [0, 0, 0, 0, 0, 0, 0, 0, 0]
  382. best = 100
  383.  
  384. if n == 0:
  385. m = 0
  386. for f in fields:
  387. fields = fieldsBackup[n]
  388. m += 1
  389.  
  390. m = 0
  391. for f in fields:
  392. if f == 0:
  393. if player > 0:
  394. f = 2
  395. if n == 0:
  396. testingField = m
  397. elif player < 0:
  398. f = 1
  399. if n == 0:
  400. testingField = m
  401. if not testforwin() == 0:
  402. testingField = 0
  403. if n < best:
  404. z = 0
  405. if testforwin() == 1:
  406. best = testingField
  407. else:
  408. best = -testingField
  409. for f in fields:
  410. f = fieldsBackup[z]
  411. z += 1
  412. else:
  413. testforbestfield(m, n + 1, -player)
  414. m += 1
  415. return best
  416. m = 0
  417. for f in fields:
  418. f = fieldsBackup[m]
  419. m += 1
  420.  
  421.  
  422.  
  423. def testforwin():
  424. global fields
  425.  
  426. if (fields[0] == fields[1] and fields[2] == fields[1] and not fields[0] == 0):
  427. return fields[0]
  428. if (fields[0] == fields[3] and fields[3] == fields[6] and not fields[0] == 0):
  429. return fields[0]
  430. if (fields[0] == fields[3] and fields[3] == fields[6] and not fields[0] == 0):
  431. return fields[0]
  432. if (fields[0] == fields[4] and fields[4] == fields[8] and not fields[0] == 0):
  433. return fields[0]
  434. if (fields[1] == fields[4] and fields[4] == fields[7] and not fields[1] == 0):
  435. return fields[1]
  436. if (fields[2] == fields[5] and fields[5] == fields[8] and not fields[2] == 0):
  437. return fields[2]
  438. if (fields[2] == fields[4] and fields[4] == fields[6] and not fields[2] == 0):
  439. return fields[2]
  440. if (fields[3] == fields[4] and fields[4] == fields[5] and not fields[3] == 0):
  441. return fields[3]
  442. if (fields[6] == fields[7] and fields[7] == fields[8] and not fields[6] == 0):
  443. return fields[6]
  444. else:
  445. return 0
  446.  
  447. def tictactoe():
  448. global starter
  449. global activeTurn
  450. global noFieldsLeft
  451. noFieldsLeft = False
  452. global fieldsToCheck
  453. global turn
  454. global idleCancel
  455. idleCancel = False
  456. turn = 0
  457. activeTurn = starter
  458. gameOver = 0
  459.  
  460. resetMov()
  461. drawGame()
  462.  
  463. while noFieldsLeft == False and gameOver == 0 and idleCancel == False:
  464. turn += 1
  465.  
  466. if activeTurn == 0:
  467. CPUTurn()
  468. activeTurn = 1
  469. elif activeTurn == 1:
  470. humanTurn()
  471. activeTurn = 0
  472.  
  473. if not testforwin() == 0:
  474. gameOver = 1
  475.  
  476. if testforwin() == 1 and idleCancel == False:
  477. rollOut()
  478. sound.speak('I won! Wohoo!')
  479. replay()
  480.  
  481. elif testforwin() == 2 and idleCancel == False:
  482. rollOut()
  483. sound.speak('Congratulations!')
  484. replay()
  485.  
  486. if testforwin() == 0 and idleCancel == False:
  487. rollOut()
  488. sound.speak('Draw! Good Game!')
  489. replay()
  490.  
  491. if __name__ == '__main__':
  492. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement