from random import choice

choice([1,2,3])

choice([1,2,3])

"""
Explanation: <h1>Table of Contents<span class="tocSkip"></span></h1>
<div class="toc"><ul class="toc-item"><li><span><a href="#Using-Turtle-graphics:-a-Tkinter-based-turtle-graphics-module-for-Python" data-toc-modified-id="Using-Turtle-graphics:-a-Tkinter-based-turtle-graphics-module-for-Python-1"><span class="toc-item-num">1&nbsp;&nbsp;</span>Using <a href="https://docs.python.org/3.6/library/turtle.html" target="_blank">Turtle graphics</a>: a <a href="https://wiki.python.org/moin/TkInter" target="_blank">Tkinter</a>-based turtle graphics module for Python</a></span><ul class="toc-item"><li><span><a href="#PacMan" data-toc-modified-id="PacMan-1.1"><span class="toc-item-num">1.1&nbsp;&nbsp;</span><a href="https://github.com/grantjenks/free-python-games/blob/master/freegames/pacman.py" target="_blank">PacMan</a></a></span></li><li><span><a href="#Exercises-(proposed-by-the-author):" data-toc-modified-id="Exercises-(proposed-by-the-author):-1.2"><span class="toc-item-num">1.2&nbsp;&nbsp;</span>Exercises (proposed by the author):</a></span></li></ul></li></ul></div>

Using Turtle graphics: a Tkinter-based turtle graphics module for Python
PacMan
Example extracted from https://github.com/grantjenks/free-python-games.
Import <a href="https://docs.python.org/3.6/library/random.html#functions-for-sequences)">choice</a> from Turtle graphics:
End of explanation
"""


from turtle import *

"""
Explanation: Import everything from Turtle graphics:
End of explanation
"""


from freegames import floor, vector # Install freegames with 'pip install freegames' 

floor(1,10) # value to floor, the floor

floor(9,10)

floor(11,10)

floor(-1,10)

floor(3,2)

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

v1 = vector(1, 2)
v2 = v1.copy()
v2.move(1)

print(v1, v2)

plt.figure()
ax = plt.gca()
ax.quiver((0,0), (0,0), (v1.x, v2.x), (v1.y, v2.y), angles='xy', scale_units='xy', scale=1)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
ax.set_xticks(np.arange(-5, 5, 1))
ax.set_yticks(np.arange(-5, 5, 1))
plt.grid()
plt.draw()
plt.show()

v1 = vector(1,2)
v2 = v1.copy()
v2.rotate(90)
print(v1, v2)

plt.figure()
ax = plt.gca()
ax.quiver((0,0), (0,0), (v1.x, v2.x), (v1.y, v2.y), angles='xy', scale_units='xy', scale=1)
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
ax.set_xticks(np.arange(-5, 5, 1))
ax.set_yticks(np.arange(-5, 5, 1))
plt.grid()
plt.draw()
plt.show()

"""
Explanation: Import floor and vector from Free Games:
End of explanation
"""


state = {'score': 0}

'score' in state

state['score']

"""
Explanation: Declare a dictionary with only one entry:
End of explanation
"""


path = Turtle(visible=False)

"""
Explanation: Instance Turtle object in instance path. Set is an invisible:
End of explanation
"""


writer = Turtle(visible=False)

aim = vector(5, 0)
pacman = vector(-40, -80)

ghosts = [
    [vector(-180, 160), vector(5, 0)],
    [vector(-180, -160), vector(0, 5)],
    [vector(100, 160), vector(0, -5)],
    [vector(100, -160), vector(-5, 0)],
]

type(ghosts)

type(ghosts[0])

type(ghosts[0][0])

"""
Explanation: Another instance:
End of explanation
"""


tiles = [
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,
    0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]

len(tiles)

type(tiles)

import matplotlib.pyplot as plt
import numpy as np
plt.matshow(np.array(tiles).reshape(20, 20))
plt.show()

def square(x, y):
    "Draw square using path at (x, y)."
    path.up()
    path.goto(x, y)
    path.down()
    path.begin_fill()

    for count in range(4):
        path.forward(20)
        path.left(90)

    path.end_fill()

square(5,7)
path.isvisible()

path.showturtle()

def offset(point):
    "Return offset of point in tiles."
    x = (floor(point.x, 20) + 200) / 20
    y = (180 - floor(point.y, 20)) / 20
    index = int(x + y * 20)
    return index

print(offset(vector(2,3)))

def valid(point):
    "Return True if point is valid in tiles."
    index = offset(point)

    if tiles[index] == 0:
        return False

    index = offset(point + 19)

    if tiles[index] == 0:
        return False

    return point.x % 20 == 0 or point.y % 20 == 0

print(valid(vector(2,3)))

"""
Explanation: The maze:
End of explanation
"""


def world():
    "Draw world using path."
    bgcolor('black')
    path.color('blue')

    for index in range(len(tiles)):
        tile = tiles[index]

        if tile > 0:
            x = (index % 20) * 20 - 200
            y = 180 - (index // 20) * 20
            square(x, y)
            print(x, y, " ",)
            if tile == 1:
                path.up()
                path.goto(x + 10, y + 10)
                path.dot(2, 'white')

#path.speed(10)
#world()

"""
Explanation: See:
* turtle.bgcolor(): Sets or return background color of the TurtleScreen.
* turtle.color(): Returns or set pencolor and fillcolor.
* turtle.up(): Pulls the pen up – no drawing when moving.
* turtle.goto(): Moves turtle to an absolute position.
* turtle.dot(): Draws a circular dot with diameter size, using color.
End of explanation
"""


def move():
    "Move pacman and all ghosts."
    writer.undo()
    writer.write(state['score'])

    clear()

    if valid(pacman + aim):
        pacman.move(aim)

    index = offset(pacman)

    if tiles[index] == 1:
        tiles[index] = 2
        state['score'] += 1
        x = (index % 20) * 20 - 200
        y = 180 - (index // 20) * 20
        square(x, y)

    up()
    goto(pacman.x + 10, pacman.y + 10)
    dot(20, 'yellow')

    for point, course in ghosts:
        if valid(point + course):
            point.move(course)
        else:
            options = [
                vector(5, 0),
                vector(-5, 0),
                vector(0, 5),
                vector(0, -5),
            ]
            plan = choice(options)
            course.x = plan.x
            course.y = plan.y

        up()
        goto(point.x + 10, point.y + 10)
        dot(20, 'red')

    update()

    for point, course in ghosts:
        if abs(pacman - point) < 20:
            return

    ontimer(move, 100)

#move()

def change(x, y):
    "Change pacman aim if valid."
    if valid(pacman + vector(x, y)):
        aim.x = x
        aim.y = y

"""
Explanation: See:
* turtle.undo(): Undoes (repeatedly) the last turtle action(s).
* turtle.write(): Writes text - the string representation of arg - at the current turtle position.
* turtle.clear(): Deletes the turtle’s drawings from the screen.
End of explanation
"""


setup(420, 420, 370, 0)
hideturtle()
tracer(False)
writer.goto(160, 160)
writer.color('white')
writer.write(state['score'])
listen()
onkey(lambda: change(5, 0), 'Right')
onkey(lambda: change(-5, 0), 'Left')
onkey(lambda: change(0, 5), 'Up')
onkey(lambda: change(0, -5), 'Down')
world()
move()
done()

"""
Explanation: See:
* turtle.setup(): Sets the size and position of the main window.
* turtle.hideturtle(): Makes the turtle invisible.
* turtle.tracer(): Turns turtle animation on/off and sets delay for update drawings.
* turtle.listen(): Sets focus on TurtleScreen (in order to collect key-events).
* turtle.onkey(): Binds a function to key-release event of key.
* turtle.done(): Starts event loop - calling Tkinter’s mainloop function.
* Lambda functions.
End of explanation
"""


