Schülerarbeit: Bimaru

Turtle Graphics

Das Bimaru von Stefan Schönenberger ist eine Kombination von Sudoku und Schiffe versenken. Es geht darum, durch logisches Kombinieren die Position verschiedener Schiffe zu finden. Bevor die Schiffe gesetzt werden können, muss die entsprechende Kategorie rechts ausgewählt (angeklickt) werden.

Der Programm-Code

#
# (c) 2014, Stefan Schoenenberger
#
from gturtle import *
from math import *
from sys import *

# ------------ Gitter Zeichnen ------------ #
def Gitter():
    hideTurtle()
    speed(-1)
    setPenColor("black")
    setColor("black")
    x = -250
    y = -250
    setPos(x, y)
    repeat 4:
        forward(500)
        right(90)
    repeat 10:
        heading(0)
        setPos(x, y)
        forward(500)
        x +=50
    repeat 10:
        heading(270)
        setPos(x, y)
        forward(500)
        y += 50
        
# ------------ Label am Rand ------------#
def Label():
    x = 284
    y = 215
    setPos(x, y)
    label("Wasser")
    setPos(x, y - 50)
    label("Schiffe:")
    setPos(x, y - 100)
    label("1er Schiff")
    setPos(x, y - 150)
    label("(4 x)")
    setPos(x, y - 200)
    label("2er Schiff")
    setPos(x, y - 250)
    label("(3 x)")
    setPos(x, y - 300)
    label("3er Schiff")
    setPos(x, y - 350)
    label("(2 x)")
    setPos(x, y - 400)
    label("4er Schiff")
    setPos(x, y - 450)
    label("(1 x)")
    setPos(-270, y)
    label("2")
    setPos(-270, y - 50)
    label("3")
    setPos(-270, y - 100)
    label("5")
    setPos(-270, y - 150)
    label("1")
    setPos(-270, y - 200)
    label("1")
    setPos(-270, y - 250)
    label("1")
    setPos(-270, y - 300)
    label("1")
    setPos(-270, y - 350)
    label("0")
    setPos(-270, y - 400)
    label("1")
    setPos(-270, y - 450)
    label("5")
    x = -230
    setPos(x, y - 500)
    label("4")
    setPos(x + 50, y - 500)
    label("0")
    setPos(x + 100, y - 500)
    label("3")
    setPos(x + 150, y - 500)
    label("3")
    setPos(x + 200, y - 500)
    label("0")
    setPos(x + 250, y - 500)
    label("3")
    setPos(x + 300, y - 500)
    label("1")
    setPos(x + 350, y - 500)
    label("1")
    setPos(x + 400, y - 500)
    label("4")
    setPos(x + 450, y - 500)
    label("1")
    
# ------------ Tutorial ------------ #
def Tutorial():
    u = input("Hast du diese Anleitung schon einmal gelesen?")
    if u == "Ja" or u == "ja":
        pass
    elif u == "Nein" or u == "nein":
        msgDlg("Ziel des Rätsels ist es, in einem Spielfeld die "+
               "versteckten Schiffe zu finden. Die Regeln: Die "+
               "Nummer am Ende jeder Zeile oder Spalte zeigt an, "+
               "wie viele Felder durch Schiffe besetzt sind. Schiffe "+
               "dürfen sich nicht berühren, weder horizontal oder "+
               "vertikal, noch diagonal. Das heißt, dass jedes Schiff"+
               "vollständig von Wasser (oder Rand) umgeben sein muss.")
        msgDlg("Um Elemente zu setzen, klicke auf 'Wasser' oder "+
               "das entsprechende Schiff, z.B. '2er Schiff'")
        msgDlg("Vergiss nicht: Schreibe bitte IMMER den Anfangsbuchstaben "+
               "gross, wenn du nach etwas gefragt wirst!")
        msgDlg("Um die Position eines Schiffes zu setzen, muss das obere "+
               "(bei einem senkrechten Schiff) resp. das linke (bei einam "+
               "waagrechten Schiff) Feld angeklickt werden.")
        msgDlg("PS: Um den Schwierigkeitsgrad zu erhöhen, kannst du nichts "+
               "löschen. Wenn du etwas falsch gemacht hast, musst du von "+
               "vorne beginnen! Und bitte nicht zu schnell hintereinander "+
               "klicken, da sonst das Programm überlasten könnte.")

spalte = 0
zeile = 0
z = 0

def Steuerung():
    global onClick
    # ------------ Clicken ------------ # (1 Quadrat = 50 Pixel lang)
    def onClick(x, y):
        global spalte, zeile, z
        spalte = x // 50
        zeile = y // 50
        xRel = x // 50 * 50
        yRel = y // 50 * 50
        # ------------ Wenn Click auf einem Aktionsfeld ist ------------#
        if 284 < x < 378 and 215 < y < 242:
            z = 0
        if 284 < x < 397 and 115 < y < 142:
            z = 1
        if 284 < x < 397 and 15 < y < 42:
            z = 2
        if 284 < x < 397 and -85 < y < -58:
            z = 3
        if 284 < x < 397 and -185 < y < -158:
            z = 4
        if -6 < spalte < 5 and -6 < zeile < 5:
            setPos(xRel + 25, yRel + 25)
            if getPixelColorStr() == "black":
                msgDlg("Geht leider nicht. Das Feld muss frei sein...")
            if getPixelColorStr() == "white":
                if z == 0:
                    # ------------ Wasser ------------ #
                    # ------------ Welle 1 ------------ #
                    def Funktion(x_W):
                        return sin(x_W * 2 * pi / 25) * 5 + 12.5
                    x_W = xRel
                    y_W = Funktion(x_W)
                    setPos(xRel, yRel + 37.5)
                    repeat 500:
                        moveTo(x_W, yRel + 25 + y_W)
                        y_W = Funktion(x_W)
                        x_W += 0.1
                    # ------------ Welle 2 ------------ #    
                    def Funktion(x_W):
                        return sin(x_W * 2 * pi / 25) * 5
                    x_W = xRel
                    y_W = Funktion(x_W)
                    setPos(xRel, yRel + 25)
                    repeat 500:
                        moveTo(x_W, yRel + 25 + y_W)
                        y_W = Funktion(x_W)
                        x_W += 0.1
                    # ------------ Welle 3 ------------ #    
                    def Funktion(x_W):
                        return sin(x_W * 2 * pi / 25) * 5 - 12.5
                    x_W = xRel
                    y_W = Funktion(x_W)
                    setPos(xRel, yRel + 12.5)
                    repeat 500:
                        moveTo(x_W, yRel + 25 + y_W)
                        y_W = Funktion(x_W)
                        x_W += 0.1
                # ------------ 1er Schiff ------------ #
                if z == 1:
                    setPos(xRel + 25, yRel + 25)
                    dot(40)
                # ------------ 2er Schiff ------------ #
                if z == 2:
                    Schiff_2 = input("Senkrecht oder Waagrecht?")
                    if Schiff_2 == "Senkrecht":
                        if zeile > -5:
                            setPos(xRel + 25, yRel - 25)
                            if getPixelColorStr() == "black":
                                msgDlg("Geht leider nicht. Ein Feld weiter "+
                                       "unter muss frei sein...")
                            if getPixelColorStr() == "white":
                                setPos(xRel + 25, yRel + 25)
                                dot(40)
                                fillToPoint()
                                setPos(xRel + 5, yRel + 25)
                                heading(90)
                                forward(40)
                                right(90)
                                forward(20)
                                right(90)
                                forward(40)
                                right(90)
                                forward(20)
                                fillOff()
                                setPos(xRel + 25, yRel - 25)
                                dot(40)
                                fillToPoint()
                                setPos(xRel + 5, yRel - 25)
                                heading(0)
                                forward(20)
                                right(90)
                                forward(40)
                                right(90)
                                forward(20)
                                right(90)
                                forward(40)
                                fillOff()
                    if Schiff_2 == "Waagrecht":
                        if spalte < 4:
                            setPos(xRel + 75, yRel + 25)
                            if getPixelColorStr() == "black":
                                msgDlg("Geht leider nicht. Ein Feld weiter "+
                                       "rechts muss frei sein...")
                            if getPixelColorStr() == "white":
                                setPos(xRel + 25, yRel + 25)
                                dot(40)
                                fillToPoint()
                                setPos(xRel + 25, yRel + 5)
                                heading(0)
                                forward(40)
                                right(90)
                                forward(20)
                                right(90)
                                forward(40)
                                right(90)
                                forward(20)
                                fillOff()
                                setPos(xRel + 75, yRel + 25)
                                dot(40)
                                fillToPoint()
                                setPos(xRel + 75, yRel + 5)
                                heading(0)
                                forward(40)
                                left(90)
                                forward(20)
                                left(90)
                                forward(40)
                                left(90)
                                forward(20)
                                fillOff()
                # ------------ 3er Schiff ------------ #
                if z == 3:
                    Schiff_3 = input("Senkrecht oder Waagrecht?")
                    if Schiff_3 == "Senkrecht":
                        if zeile > -4:
                            setPos(xRel + 25, yRel - 25)
                            if getPixelColorStr() == "black":
                                msgDlg("Geht leider nicht. Ein Feld weiter "+
                                       "unter muss frei sein...")
                            if getPixelColorStr() == "white":
                                setPos(xRel + 25, yRel - 75)
                                if getPixelColorStr() == "black":
                                    msgDlg("Geht leider nicht. Zwei Felder "+
                                           "weiter unter muss frei sein...")
                                if getPixelColorStr() == "white":
                                    setPos(xRel + 25, yRel + 25)
                                    dot(40)
                                    fillToPoint()
                                    setPos(xRel + 5, yRel + 25)
                                    heading(90)
                                    forward(40)
                                    right(90)
                                    forward(20)
                                    right(90)
                                    forward(40)
                                    right(90)
                                    forward(20)
                                    fillOff()
                                    setPos(xRel + 5, yRel - 5)
                                    fillToPoint()
                                    heading(180)
                                    repeat 4:
                                        forward(40)
                                        left(90)
                                    fillOff()
                                    setPos(xRel + 25, yRel - 75)
                                    dot(40)
                                    setPos(xRel + 5, yRel - 75)
                                    fillToPoint()
                                    heading(0)
                                    forward(20)
                                    right(90)
                                    forward(40)
                                    right(90)
                                    forward(20)
                                    right(90)
                                    forward(40)
                                    fillOff()
                    if Schiff_3 == "Waagrecht":
                        if spalte < 3:
                            setPos(xRel + 75, yRel + 25)
                            if getPixelColorStr() == "black":
                                msgDlg("Geht leider nicht. Ein Feld weiter "+
                                       "rechts muss frei sein...")
                            if getPixelColorStr() == "white":
                                setPos(xRel + 125, yRel + 25)
                                if getPixelColorStr() == "black":
                                    msgDlg("Geht leider nicht. Zwei Felder "+
                                           "weiter rechts muss frei sein...")
                                if getPixelColorStr() == "white":
                                    setPos(xRel + 25, yRel + 25)
                                    dot(40)
                                    setPos(xRel + 25, yRel + 5)
                                    fillToPoint()
                                    heading(0)
                                    forward(40)
                                    right(90)
                                    forward(20)
                                    right(90)
                                    forward(40)
                                    right(90)
                                    forward(20)
                                    fillOff()
                                    setPos(xRel + 55, yRel + 5)
                                    fillToPoint()
                                    heading(0)
                                    repeat 4:
                                        forward(40)
                                        right(90)
                                    fillOff()
                                    setPos(xRel + 125, yRel + 25)
                                    dot(40)
                                    setPos(xRel + 125, yRel + 5)
                                    fillToPoint()
                                    heading(0)
                                    forward(40)
                                    left(90)
                                    forward(20)
                                    left(90)
                                    forward(40)
                                    left(90)
                                    forward(20)
                                    fillOff()
                # ------------ 4er Schiff ------------ #
                if z == 4:
                    Schiff_4 = input("Senkrecht oder Waagrecht?")
                    if Schiff_4 == "Senkrecht":
                        if zeile > -3:
                            setPos(xRel + 25, yRel - 25)
                            if getPixelColorStr() == "black":
                                msgDlg("Geht leider nicht. Ein Feld weiter "+
                                       "unten muss frei sein...")
                            elif getPixelColorStr() == "white":
                                setPos(xRel + 25, yRel - 75)
                                if getPixelColorStr() == "black":
                                    msgDlg("Geht leider nicht. Zwei Felder "+
                                           "weiter unten muss frei sein...")
                                elif getPixelColorStr() == "white":
                                    setPos(xRel + 25, yRel - 125)
                                    if getPixelColorStr() == "black":
                                        msgDlg("Geht leider nicht. Drei Felder "+
                                               "weiter unten muss frei sein...")
                                    elif getPixelColorStr() == "white":
                                        setPos(xRel + 25, yRel + 25)
                                        dot(40)
                                        setPos(xRel + 5, yRel + 5)
                                        fillToPoint()
                                        heading(0)
                                        forward(20)
                                        right(90)
                                        forward(40)
                                        right(90)
                                        forward(20)
                                        right(90)
                                        forward(40)
                                        fillOff()
                                        setPos(xRel + 5, yRel - 5)
                                        fillToPoint()
                                        heading(90)
                                        repeat 4:
                                            forward(40)
                                            right(90)
                                        fillOff()
                                        setPos(xRel + 5, yRel - 55)
                                        fillToPoint()
                                        heading(90)
                                        repeat 4:
                                            forward(40)
                                            right(90)
                                        fillOff()
                                        setPos(xRel + 25, yRel - 125)
                                        dot(40)
                                        setPos(xRel + 5, yRel - 125)
                                        fillToPoint()
                                        heading(0)
                                        forward(20)
                                        right(90)
                                        forward(40)
                                        right(90)
                                        forward(20)
                                        right(90)
                                        forward(40)
                                        fillOff()
                    if Schiff_4 == "Waagrecht":
                        if spalte < 2:
                            setPos(xRel + 75, yRel + 25)
                            if getPixelColorStr() == "black":
                                msgDlg("Geht leider nicht. Ein Feld weiter "+
                                       "rechts muss frei sein...")
                            elif getPixelColorStr() == "white":
                                setPos(xRel + 125, yRel + 25)
                                if getPixelColorStr() == "black":
                                    msgDlg("Geht leider nicht. Zwei Felder "+
                                           "weiter rechts muss frei sein...")
                                elif getPixelColorStr() == "white":
                                    setPos(xRel + 175, yRel + 25)
                                    if getPixelColorStr() == "black":
                                        msgDlg("Geht leider nicht. Drei Felder "+
                                               "weiter rechts muss frei sein...")
                                    elif getPixelColorStr() == "white":
                                        setPos(xRel + 25, yRel + 25)
                                        dot(40)
                                        setPos(xRel + 25, yRel + 5)
                                        fillToPoint()
                                        heading(0)
                                        forward(40)
                                        right(90)
                                        forward(20)
                                        right(90)
                                        forward(40)
                                        right(90)
                                        forward(20)
                                        fillOff()
                                        setPos(xRel + 55, yRel + 5)
                                        fillToPoint()
                                        heading(0)
                                        repeat 4:
                                            forward(40)
                                            right(90)
                                        fillOff()
                                        setPos(xRel + 105, yRel + 5)
                                        fillToPoint()
                                        heading(0)
                                        repeat 4:
                                            forward(40)
                                            right(90)
                                        fillOff()
                                        setPos(xRel + 175, yRel + 25)
                                        dot(40)
                                        setPos(xRel + 175, yRel + 5)
                                        fillToPoint()
                                        heading(0)
                                        forward(40)
                                        left(90)
                                        forward(20)
                                        left(90)
                                        forward(40)
                                        left(90)
                                        forward(20)
                                        fillOff()

            Ende()
            
def FesteBloecke():                                        
    # ------------ Feste Schiffe ------------ #
    setPos(-75, -25)
    dot(40)
    setPos(-95, -25)
    fillToPoint()
    heading(90)
    forward(40)
    right(90)
    forward(20)
    right(90)
    forward(40)
    right(90)
    forward(20)
    fillOff()
    setPos(-75, -25)
    setPenColor("white")
    forward(1)
    setPos(25, 125)
    dot(40)
    setPos(5, 105)
    setPenColor("black")
    fillToPoint()
    heading(0)
    repeat 4:
        forward(40)
        right(90)
    fillOff()
    setPenColor("white")
    setPos(25, 125)
    forward(1)
    setPenColor("black")
    # ------------ Festes Wasser ------------ #
    # ------------ Welle 1 ------------ #
    def Funktion(x_W):
        return sin(x_W * 2 * pi / 25) * 5 + 12.5
    x_W = -250
    y_W = Funktion(x_W)
    setPos(-250, 200 + 37.5)
    repeat 500:
        moveTo(x_W, 200 + 25 + y_W)
        y_W = Funktion(x_W)
        x_W += 0.1
    # ------------ Welle 2 ------------ #    
    def Funktion(x_W):
        return sin(x_W * 2 * pi / 25) * 5
    x_W = -250
    y_W = Funktion(x_W)
    setPos(-250, 200 + 25)
    repeat 500:
        moveTo(x_W, 200 + 25 + y_W)
        y_W = Funktion(x_W)
        x_W += 0.1
    # ------------ Welle 3 ------------ #    
    def Funktion(x_W):
        return sin(x_W * 2 * pi / 25) * 5 - 12.5
    x_W = -250
    y_W = Funktion(x_W)
    setPos(-250, 200 + 12.5)
    repeat 500:
        moveTo(x_W, 200 + 25 + y_W)
        y_W = Funktion(x_W)
        x_W += 0.1
        
    # ------------ Welle 1 ------------ #
    def Funktion(x_W):
        return sin(x_W * 2 * pi / 25) * 5 + 12.5
    x_W = -150
    y_W = Funktion(x_W)
    setPos(-150, -200 + 37.5)
    repeat 500:
        moveTo(x_W, -200 + 25 + y_W)
        y_W = Funktion(x_W)
        x_W += 0.1
    # ------------ Welle 2 ------------ #    
    def Funktion(x_W):
        return sin(x_W * 2 * pi / 25) * 5
    x_W = -150
    y_W = Funktion(x_W)
    setPos(-150, -200 + 25)
    repeat 500:
        moveTo(x_W, -200 + 25 + y_W)
        y_W = Funktion(x_W)
        x_W += 0.1
    # ------------ Welle 3 ------------ #    
    def Funktion(x_W):
        return sin(x_W * 2 * pi / 25) * 5 - 12.5
    x_W = -150
    y_W = Funktion(x_W)
    setPos(-150, -200 + 12.5)
    repeat 500:
        moveTo(x_W, -200 + 25 + y_W)
        y_W = Funktion(x_W)
        x_W += 0.1
        
# ------------ Main ------------ #
Tutorial()
Steuerung()
makeTurtle(mouseHit = onClick)
Gitter()
Label()
FesteBloecke()

#------------- Sieg ------------#
def Ende():
    Originalliste = [
        0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 
        0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
        0, 1, 1, 1, 1
      ]
    penUp()
    Spielerliste = []
    b = 222
    repeat 10:
        for i in range(1, 11):
            setPos(50 * i - 275, b)
            if getPixelColorStr() == "black":
                Spielerliste.append(1)
            else:
                Spielerliste.append(0)
            heading(90)
            i+=1
        b -= 50
    penDown()
    summe = sum(Spielerliste)
    if summe >= 20:
        if Originalliste == Spielerliste:
            msgDlg("Du hast gewonnen!")
            exit()
        else:
            msgDlg("Du hast verloren!")
            exit()