Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # Import aus Library
- import os
- import sys
- import time
- from ev3dev2.sensor.lego import TouchSensor, ColorSensor
- from ev3dev2.sensor import INPUT_1, INPUT_4, INPUT_3
- from ev3dev2.sound import Sound
- from ev3dev2.led import Leds
- from ev3dev2.button import Button
- from random import randrange
- from math import inf
- from ev3dev2.motor import LargeMotor, MediumMotor, OUTPUT_A, OUTPUT_B, OUTPUT_C, OUTPUT_D, SpeedPercent, MoveTank
- #region Hintergrund-Einstellungen (notwendig für Kompatibilität)
- def debug_print(*args, **kwargs):
- print(*args, **kwargs, file=sys.stderr)
- btn = Button()
- leds = Leds()
- sound = Sound()
- ON = True
- OFF = False
- #
- def reset_console():
- print('\x1Bc', end='')
- def set_cursor(state):
- if state:
- print('\x1B[?25h', end='')
- else:
- print('\x1B[?25l', end='')
- def set_font(name):
- os.system('setfont ' + name)
- #endregion
- def rockpaperscissors(): # Funktion für Schere, Stein, Papier
- # Globale Variablen
- global starter
- rpsResult = 0 # Ergebnis von Schere, Stein, Papier
- rpsAI = 0 # SSP-Auswahl des Computers
- leds.set_color("LEFT", "AMBER")
- leds.set_color("RIGHT", "AMBER")
- time.sleep(1)
- sound.speak('Please use the right, left or down button to select either rock, paper or scissors.')
- sound.speak('The left button will result in rock, the down button will result in paper and the right button will result in scissors.')
- sound.speak('Then use the center button to confirm your choice.')
- while rpsResult == 0: # Solange kein Ergebnis erreicht wurde, wiederholt sich die Schleife
- if btn.left:
- rps = 1 # Auswahl wird auf Stein gesetzt
- leds.set_color("LEFT", "ORANGE")
- leds.set_color("RIGHT", "BLACK")
- sound.speak('Rock is now selected.')
- elif btn.down:
- rps = 2 # Auswahl wird auf Papier gesetzt
- leds.set_color("LEFT", "ORANGE")
- leds.set_color("RIGHT", "ORANGE")
- sound.speak('Paper is now selected.')
- elif btn.right:
- rps = 3 # Auswahl wird auf Schere gesetzt
- leds.set_color("RIGHT", "ORANGE")
- leds.set_color("LEFT", "BLACK")
- sound.speak('Scissors is now selected.')
- elif btn.enter:
- if rps == 0: # Wenn der Spieler sich noch nicht entschieden hat, muss er nochmal bestätigen
- sound.speak('Please select either rock, paper or scissors first.')
- else:
- rpsAI = randrange(2) + 1 # Berechnung der Computer-Auswahl
- if rps == rpsAI: # Wenn der Spieler und der Computer das gleiche gewählt haben, muss nochmal gespielt werden
- if rps == 1:
- sound.speak("You both chose rock. Please play again.")
- elif rps == 2:
- sound.speak("You both chose paper. Please play again.")
- elif rps == 3:
- sound.speak("You both chose scissors. Please play again.")
- elif rps == 1: # Wenn der Spieler Stein wählt..
- if rpsAI == 2: # ..und der Computer Papier,..
- rpsResult = 2 # ..dann gewinnt der Computer
- elif rpsAI == 3: # ..und der Computer Schere,..
- rpsResult = 1 # ..dann gewinnt der Spieler
- elif rps == 2: # Wenn der Spieler Papier wählt..
- if rpsAI == 1: # ..und der Computer Stein,..
- rpsResult = 1 # ..dann gewinnt der Spieler
- elif rpsAI == 3: # ..und der Computer Schere,..
- rpsResult = 2 # ..dann gewinnt der Computer
- elif rps == 3: # Wenn der Spieler Schere wählt..
- if rpsAI == 1: # ..und der Computer Stein,..
- rpsResult = 2 # ..dann gewinnt der Computer
- elif rpsAI == 2: # ..und der Computer Papier,..
- rpsResult = 1 # ..dann gewinnt der Spieler
- if rpsResult == 1: # Wenn der Spieler gewinnt, wird der Start-Wert auf Spieler (1) gesetzt und Tic-Tac-Toe gestartet
- leds.set_color("RIGHT", "GREEN")
- leds.set_color("LEFT", "GREEN")
- sound.speak("Congratulations! You won this time and you may now start.")
- starter = 1
- tictactoe()
- elif rpsResult == 2: # Wenn der Computer gewinnt, wird der Start-Wert auf Computer (0) gesetzt und Tic-Tac-Toe gestartet
- leds.set_color("LEFT", "RED")
- leds.set_color("RIGHT", "RED")
- sound.speak("You unfortunately lost. The computer will start.")
- starter = 0
- tictactoe()
- def main():
- # Einrichtung zur Kompatibilität
- reset_console()
- set_cursor(OFF)
- set_font('Lat15-Terminus24x12')
- # Globale Variablen
- global pen
- global xMax
- global yMax
- global xPos
- global yPos
- global fields
- fields = [0, 0, 0, 0, 0, 0, 0, 0, 0] # Array, welches Feld von welchem Spieler bemalt ist
- xPos = 0 # x-Position des Stiftes
- yPos = 0 # y-Position des Stiftes
- xMax = 300 # Maximaler x-Wert des Feldes
- yMax = 220 # Maxmimaler y-Wert des Feldes
- pen = 1 # Position des Stiftes
- leds.all_off()
- time.sleep(1)
- leds.set_color("LEFT", "RED")
- leds.set_color("RIGHT", "RED")
- time.sleep(1)
- sound.speak('Welcome to Tic Tac Toe by Johannes Peters and Niels Hannemann.')
- sound.speak('Press the right button for a slow start with rock, papers and scissors.')
- sound.speak('Press the middle button for a quick start.')
- time.sleep(1)
- leds.set_color("LEFT", "AMBER")
- leds.set_color("RIGHT", "AMBER")
- while True:
- if btn.enter: # Wenn der Spieler den Schnellstart wählt. wird ein zufälliger Starter ausgewählt
- starter = randrange(0, 2) + 1
- tictactoe()
- elif btn.right: # Wenn der Spieler Schere, Stein, Papier wählt, wird die Funktion aufgerufen
- rockpaperscissors()
- def pendown(): # Funktion zur Bewegung des Stiftes in die untere Position
- # Globale Variablen
- global pen
- m = MediumMotor(OUTPUT_C) # Initialisierung des Motors
- if pen == 0: # Checken, ob der Stift bereits in der unteren Position ist - wenn dem so ist, wird der Stift nicht weiter bewegt
- return
- m.on_for_rotations(SpeedPercent(-10), 0.086)
- pen = 0 # Stift-Position wird nach unten versetzt
- def penup(): # Funktion zur Bewegung des Stiftes in die obere Position
- # Globale Variablen
- global pen
- m = MediumMotor(OUTPUT_C) # Initialisierung des Motors
- if pen == 1: # Checken, ob der Stift bereits in der oberen Position ist - wenn dem so ist, wird der Stift nicht weiter bewegt
- return
- m.on_for_rotations(SpeedPercent(10), 0.086)
- pen = 1 # Stift-Position wird nach unten versetzt
- def drawGame(): # Funktion zum Zeichnen des Spielfelds
- # Globale Variablen
- global xMax
- global yMax
- # Abmessungen des Spielfelds, jeweils Linien auf 1/3 und 2/3 der gesamten Länge bzw. Breite
- draw((1/3) * xMax, 0, (1/3) * xMax, yMax, False)
- draw((2/3) * xMax, 0, (2/3) * xMax, yMax, False)
- draw(0, (1/3) * yMax, xMax, (1/3) * yMax, False)
- draw(0, (2/3) * yMax, xMax, (2/3) * yMax, False)
- def resetMov(): # Funktion zum Zurücksetzen des Scan & Zeichenblocks mit Motor an Port C (x-Richtung)
- ts = TouchSensor(INPUT_1) # Initialisierung des Drucksensors
- m = MediumMotor(OUTPUT_C) # Initialisierung des Motors
- while not ts.is_pressed: # Block wird solange in x-Richtung bewegt, bis Drucksensor durch den Block gedrückt worden ist
- xMot = LargeMotor(OUTPUT_D) # Initialisierung des Motors
- xMot.on(30, 30)
- if ts.is_pressed:
- xMot.stop()
- penup() # Stift wird in die obere Position bewegt
- xPos = 0 # x-Position wird angepasst/zurückgesetzt
- def drawX(): # Funktion zum Zeichnen des CPU-Symbols auf dem Spielfeld
- # Globale Variablen
- global xPos
- global yPos
- global activeField
- global fields
- ancleX = xPos # Ankerpunkt-Variable
- ancleY = yPos # Ankerpunkt-Variable
- width = 25 # Größe des Symbols
- # Das Symbol wird gezeichnet
- move(ancleX - width, ancleY - width, False)
- pendown()
- move(ancleX + width, ancleY - width, False)
- move(ancleX + width, ancleY + width, False)
- move(ancleX - width, ancleY + width, False)
- move(ancleX - width, ancleY - width, False)
- penup()
- fields[activeField] = 1 # Spieler-Zug wird in das Array eingetragen
- def moveToField(i): # Funktion zur Bewegung zum ausgewählten Feld
- # Globale Variablen
- global xMax
- global yMax
- global activeField
- if i == 6: #Feld unten links
- move((1/6) * xMax, (1/6) * yMax, False)
- activeField = i
- elif i == 7: #Feld unten mittig
- move(0.5 * xMax, (1/6) * yMax, False)
- activeField = i
- elif i == 8: #Feld unten rechts
- move((5/6) * xMax + 15, (1/6) * yMax, False)
- activeField = i
- elif i == 3: #Feld mittig links
- move((1/6) * xMax, 0.5 * yMax - 5, False)
- activeField = i
- elif i == 4: #Feld Mitte
- move(0.5 * xMax, 0.5 * yMax - 5, False)
- activeField = i
- elif i == 5: #Feld mittig rechts
- move((5/6) * xMax, 0.5 * yMax - 5, False)
- activeField = i
- elif i == 0: #Feld oben links
- move((1/6) * xMax, (5/6) * yMax, False)
- activeField = i
- elif i == 1: #Feld oben mittig
- move(0.5 * xMax, (5/6) * yMax, False)
- activeField = i
- elif i == 2: #Feld oben rechts
- move((5/6) * xMax, (5/6) * yMax, False)
- activeField = i
- def checkField(i): #Funktion zum Auszesen, ob und wo der Spieler sein "Kreuz" gesetzt hat
- global xPos
- global yPos
- global fields
- global change
- moveToField(i) #Bewegung zum Feld
- cs = ColorSensor(INPUT_4) #Input des Farbsensors
- move(xPos + 32, yPos - 40, False) #Leichte Positionsänderung, damit der Farbsensor optimal zum Auslesen platziert ist
- if i == 0 or i == 1 or i == 2: #Weitere Positionsänderungen für einzelne Felder (obere Reihe und das rechte untere Feld)
- move(xPos, yPos - 7, False)
- elif i == 8:
- move(xPos - 5, yPos, False)
- if not (cs.color == 6 or cs.color == 0): #Wenn die erkannte Farbe nicht weiß oder unerkannt ist,
- fields[i] = 2 #wird das Feld in der Liste als vom Spieler bespielt gesetzt (0 -> unbesetzt, 1 -> CPU, 2 -> Spieler) und
- change += 1 #die "change"-Variable um 1 erhöht, sodass die CPU kontrollieren kann, dass nur genau ein Feld verändert wurde
- if change == 1:
- sound.speak('Good move!')
- elif not change == 1:
- sound.speak('Wait a second!')
- def checkFields():
- global fieldsToCheck
- global noFieldsLeft
- global fieldsLeft
- fieldsLeft = 0
- fieldsToCheck = ["0", "0", "0", "0", "0", "0", "0", "0", "0"]
- noFieldsLeft = True
- n = 8
- s = 0
- m = 0
- change = 0
- for counter in range(0, n + 1):
- if fields[s] == 0:
- checkField(s)
- if fields[s] == 0:
- fieldsToCheck[m] = s
- fieldsLeft += 1
- noFieldsLeft = False
- m += 1
- s += 1
- 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)
- penup()
- move(x, y, False)
- time.sleep(0.3)
- pendown()
- time.sleep(0.5)
- move(x2, y2, dia)
- penup()
- def rollOut(): #Funktion zum Herausrollen des Papiers
- global xPos
- global yPos
- move(xPos, 380, False)
- def move(x, y, dia):
- global xPos
- global yPos
- xMov = x - xPos
- yMov = y - yPos
- xMot = LargeMotor(OUTPUT_D)
- yMot = LargeMotor(OUTPUT_A)
- tank_drive = MoveTank(OUTPUT_D, OUTPUT_A)
- if dia == True:
- tank_drive.on_for_degrees(SpeedPercent(-30), SpeedPercent(30), xMov, yMov)
- else:
- xMot.on_for_degrees(SpeedPercent(-15), xMov)
- yMot.on_for_degrees(SpeedPercent(15), yMov)
- xPos += xMov
- yPos += yMov
- def CPUTurn():
- global turn
- global idleCancel
- global fieldsLeft
- global fieldsToCheck
- idleCancel = False
- moveToField(testforbestfield(0, -1))
- #moveToField(fieldsToCheck[randrange(0, fieldsLeft + 1)])
- drawX()
- def humanTurn():
- global change
- global idleCancel
- change = 0
- idleCancel = False
- ts = TouchSensor(INPUT_3)
- while change == 0:
- rollOut()
- sound.speak('Your turn!')
- while not ts.is_pressed:
- time.sleep(0.0001)
- checkFields()
- if change == 0:
- sound.speak('Sorry, I could not recognize your move. Please try again!')
- if change >= 2:
- sound.speak('Please only do one move at a time. The game will be disrupted.')
- idleCancel = True
- def replay():
- ts = TouchSensor(INPUT_3)
- sound.speak('Press the enter button to quickplay again!')
- sound.speak('Press the right button to play with rock, papers and scissors.')
- while not ts.is_pressed:
- sound.speak('Please put in another blank paper!')
- move(0, 0, False)
- while not btn.any():
- if btn.enter:
- tictactoe()
- elif btn.right:
- rockpaperscissors()
- def testforbestfield(n, player):
- global fields
- testingField = 0
- fieldsBackup = [0, 0, 0, 0, 0, 0, 0, 0, 0]
- best = 100
- if n == 0:
- m = 0
- for f in fields:
- fields = fieldsBackup[n]
- m += 1
- m = 0
- for f in fields:
- if f == 0:
- if player > 0:
- f = 2
- if n == 0:
- testingField = m
- elif player < 0:
- f = 1
- if n == 0:
- testingField = m
- if not testforwin() == 0:
- testingField = 0
- if n < best:
- z = 0
- if testforwin() == 1:
- best = testingField
- else:
- best = -testingField
- for f in fields:
- f = fieldsBackup[z]
- z += 1
- else:
- testforbestfield(m, n + 1, -player)
- m += 1
- return best
- m = 0
- for f in fields:
- f = fieldsBackup[m]
- m += 1
- def testforwin():
- global fields
- if (fields[0] == fields[1] and fields[2] == fields[1] and not fields[0] == 0):
- return fields[0]
- if (fields[0] == fields[3] and fields[3] == fields[6] and not fields[0] == 0):
- return fields[0]
- if (fields[0] == fields[3] and fields[3] == fields[6] and not fields[0] == 0):
- return fields[0]
- if (fields[0] == fields[4] and fields[4] == fields[8] and not fields[0] == 0):
- return fields[0]
- if (fields[1] == fields[4] and fields[4] == fields[7] and not fields[1] == 0):
- return fields[1]
- if (fields[2] == fields[5] and fields[5] == fields[8] and not fields[2] == 0):
- return fields[2]
- if (fields[2] == fields[4] and fields[4] == fields[6] and not fields[2] == 0):
- return fields[2]
- if (fields[3] == fields[4] and fields[4] == fields[5] and not fields[3] == 0):
- return fields[3]
- if (fields[6] == fields[7] and fields[7] == fields[8] and not fields[6] == 0):
- return fields[6]
- else:
- return 0
- def tictactoe():
- global starter
- global activeTurn
- global noFieldsLeft
- noFieldsLeft = False
- global fieldsToCheck
- global turn
- global idleCancel
- idleCancel = False
- turn = 0
- activeTurn = starter
- gameOver = 0
- resetMov()
- drawGame()
- while noFieldsLeft == False and gameOver == 0 and idleCancel == False:
- turn += 1
- if activeTurn == 0:
- CPUTurn()
- activeTurn = 1
- elif activeTurn == 1:
- humanTurn()
- activeTurn = 0
- if not testforwin() == 0:
- gameOver = 1
- if testforwin() == 1 and idleCancel == False:
- rollOut()
- sound.speak('I won! Wohoo!')
- replay()
- elif testforwin() == 2 and idleCancel == False:
- rollOut()
- sound.speak('Congratulations!')
- replay()
- if testforwin() == 0 and idleCancel == False:
- rollOut()
- sound.speak('Draw! Good Game!')
- replay()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement