-1

Good morning I have a project where I must code a game that looks like this: http://www.apppicker.com/apps/1055267582/1010-hex-fit--block-puzzle-mania-archanoid-pixduel-plus-saga-free-game? And I must code the game without classes ("class"), because my school doesn't want me to :(.

Now, I have already drawn the grid perfectly, but unfortunatly I can't seem to make my pawns go on the exact hexagonal "squares"n because it's not a traditional grid. Can someone help me on that? And how can I assign an array with values to it?

And if you can't do anything with this issue can you at least guide me on something else?

(I changed my program a bit from the last version of my post to make it clearer)

Thank in advance for your time.

from tkinter import *
from random import choice #for colors

beige = (255,228,196)

def dessus(evt): #mouse on hexagonal pawn
    forme = "arrow"
    if x_pion - 50 < evt.x < x_pion + 50 and y_pion - 100 < evt.y < y_pion + 100:
        forme = "fleur"
        # print(x_pion , y_pion)
    can.config(cursor = forme)

def glisser(evt): #mouse dragging the hexagonal pawn
    global x, y
    if x == -1 :
        if x_pion - 50 < evt.x < x_pion + 50 and y_pion - 100 < evt.y < y_pion + 100:
            x, y = evt.x, evt.y
    else :
        delta_x, delta_y = evt.x - x, evt.y - y
        can.coords(pion, x_pion + delta_x, y_pion + delta_y)


def coord_case(x_pos,y_pos):
    # return hexagonal coordinates spot from the game board
    coord_x = x_pos//c
    coord_y = y_pos//c
    print(x_pos, y_pos)
    return coord_x, coord_y



def coord_image(x_pos,y_pos):
    # return the coordinates of the image
    x = c * x_pos + dc
    y = c * y_pos + dc
    return x, y


def deposer(evt): #put/release the image (hexagonal pawn) on the screen
    global x_pion, y_pion, x
    if x != -1:
        x_pion, y_pion = x_pion + evt.x - x, y_pion + evt.y - y
        x =- 1

def hexagone(origine, c): #draws the hexagones
    seg = c / 4
    x, y = origine[0], origine[1]
    # hexagone
    can.create_polygon(x,y+seg, x+2*seg,y, x+c,y+seg, x+c,y+3*seg ,x+2*seg,y+c ,x,y+3*seg, x,y+seg,
                       outline='black', width=1, fill="beige")


def ligne_d_hexagones(x, y, c, n): #draws the hexagonal lines
    i = 0
    seg = c / 4
    while i < n:
        hexagone((x + 2, y + 2), c)  # +2 :
        i += 1
        x += 4.25 * seg


def damier(c, nl, nc):
    #finally draws everything (the hexagonal game board)
    x = 2.08 # commencera la ligne
    y = 0.02
    i = 1
    for i in range(nc-1):
        ligne_d_hexagones(x * c, y * c, c, nc // 2)
        i+=1
        y = y + 0.79
        if i < 5:
            nc = nc + 2
            x = x - 0.52
        if i == 5:
            nc = nc - 2
            x = x + 0.52
        if i > 5:
            nc = nc - 2
            x = x + 0.52



c = 70  # size of the hexagones from the board
nl = 10  # number of lines
nc = 10  # number of columns (this valuer will change)
dc = c//2
fen = Tk()
fen.title("HEX1010")

can = Canvas(fen, width=1000, height=700)
can.pack(side=TOP)
damier(c, nl, nc)
can.grid()


x, y = -1, -1
f_pion = PhotoImage(file="HEX.png")
x_pion, y_pion = 600, 600
pion = can.create_image(x_pion, y_pion,image=f_pion)

x, y, num = -1, -1, -1

can.bind('<B1-Motion>',glisser)
can.bind('<ButtonRelease-1>',deposer)
can.bind('<Motion>',dessus)

fen.mainloop()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
Tim Soph
  • 35
  • 6

1 Answers1

0

I eventually found a bit of time to look at your code...

1- you need to read a little bit about canvas items and how they can be accessed, identified, and made to reveal their state and position, that will help you decide how to structure your app. At this moment, you were mostly trying to account for each item, instead of using the canvas methods.

2- I added a dictionary to hold a mapping of the grid hexagons to their center positions; the key is the canvas item number of each hexagon.

3- I identify the hexagon the mouse is over using canvas.find_overlapping, and use this return value to look up into the centers dictionary of tile centers, to snap the 'pion' to the correct position.

Mostly it does what you wanted, but it is probably a bit brittle: for instance, 2 pions can be placed on top of each other. It may break on some special cases. My suggestion is to rewrite the entire code using a class for the Cases, a class for the Damier, a class for the Pion, and a class for the Pions, and equip them with the methods you need to let them behave the way you want.

from tkinter import *


beige = (255,228,196)


def selectioner(evt):
    global x, y, num
    x, y = evt.x, evt.y
    x0, y0, x1, y1 = x - 3, y - 3, x + 3, y + 3
    for item in can.find_overlapping(x0, y0, x1, y1):
        if item in pion:
            num = item
            x, y = can.coords(num)
            break


def glisser(evt): #mouse dragging the hexagonal pawn
    global x, y, num
    if num == -1 :
        pass
    else :
        delta_x, delta_y = evt.x - x, evt.y - y
        can.coords(num, x + delta_x, y + delta_y)


def deposer(evt): #put/release the image (hexagonal pawn) on the screen
    global num

    if num == -1:
        return

    x0, y0, x1, y1 = evt.x - 3, evt.y - 3, evt.x + 3, evt.y + 3
    snap = None
    for item in can.find_overlapping(x0, y0, x1, y1):
        try:
            snap = centers[item]
            break
        except KeyError:
            pass        
    if num != -1 and snap is not None:
        xs, ys = snap
        can.coords(num, xs, ys)
    num = -1


def hexagone(origine, c): #draws the hexagones
    seg = c / 4
    x, y = origine[0], origine[1]
    center = center_x, center_y = (x + x+c) / 2, (y+seg + y+3*seg) / 2
    p = can.create_polygon(x, y+seg, x+2*seg, y, x+c, y+seg, x+c, y+3*seg , x+2*seg, y+c , x,y+3*seg, x,y+seg,
                       outline='black', width=1, fill="beige")
#     can.create_oval(center_x-2, center_y-2, center_x+2, center_y+2)
    centers[p] = center


def ligne_d_hexagones(x, y, c, n): #draws the hexagonal lines
    i = 0
    seg = c / 4
    while i < n:
        hexagone((x + 2, y + 2), c)  # +2 : 
        i += 1
        x += 4.25 * seg


def damier(c, nl, nc):
    # finally draws everything (the hexagonal game board)
    x = 2.08 # commencera la ligne
    y = 0.02
    i = 1
    for i in range(nc-1):
        ligne_d_hexagones(x * c, y * c, c, nc // 2)
        i+=1
        y = y + 0.79
        if i < 5:
            nc = nc + 2
            x = x - 0.52
        if i == 5:
            nc = nc - 2
            x = x + 0.52
        if i > 5:
            nc = nc - 2
            x = x + 0.52


centers = {}

c = 70  # size of the hexagones from the board
nl = 10  # number of lines 
nc = 10  # number of columns (this valuer will change)
dc = c//2
fen = Tk()
fen.title("HEX1010")

can = Canvas(fen, width=1000, height=700)
can.pack(side=TOP)
damier(c, nl, nc)
can.grid()

pion, x_pion, y_pion = [], [], []
f_pion = PhotoImage(file="HEX.png")
for i in range(3):
    idx, idy = 300*(i+1), 300
    x_pion.append(idx)
    y_pion.append(idy)
    pion.append(can.create_image(idx,idy,image=f_pion))

x, y, num = -1, -1, -1

can.bind('<Button-1>', selectioner)
can.bind('<B1-Motion>', glisser)
can.bind('<ButtonRelease-1>', deposer)

fen.mainloop()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • Thank you very much, YOU DID AN AMAZING JOB! For the classes I'm gonna look at them a bit, but overall, thank you, I'm gonna get a closer look at the code ASAP! (and if I have more questions, can I ask them to you? If that doesn't bother you?) – Tim Soph Sep 06 '18 at 06:18
  • but how about an array? Linked to the tiles? With 0 when there are no pions and 1 when there are? It could prevent the pions to share the same place.... – Tim Soph Sep 08 '18 at 20:20
  • Yes, that's a possibility; you could also make use of the `centers` dictionary, to store if a cell is occupied. – Reblochon Masque Sep 08 '18 at 22:56
  • Hi, quick note. I'm gonna remove part of the code for now because I don't want anyone in my campus to have the same solution for the project as me. Maybe I'm going to repost it after my project has been corrected. Which means only you and I have the original (I hope) code for now. I hope you understand... – Tim Soph Sep 11 '18 at 17:56
  • 2
    I rejected your edit, this is not how this site works. – Reblochon Masque Sep 11 '18 at 18:08
  • I'm soooo sorry. (I didn't mean to insult you or offend you in any way). I totally understand, and sorry for those bad edits, won't happen again now that I understand how it works... hope you can forgive me though :( – Tim Soph Sep 11 '18 at 20:08
  • No worries, there is sometimes a misunderstanding of what stackoverflow's purpose is; I recommend taking the [tour], and also visiting the [help] when you have some time. – Reblochon Masque Sep 12 '18 at 01:29
  • 1
    The proper approach to your assignment, is to cite, and give reference to outside resources you used, and the help you obtained; this is the way these things work in 'real life' too; it shows your teachers that you know that giving credit is how the game is played, and will beam the flashlight on those that might use the same code, but without citation. Further, your teachers are not fools, they know the site, and know how to conduct a search. Most universities also use plagiarism detection algorithms that can tell if a piece of code was "inspired" by another. – Reblochon Masque Sep 12 '18 at 01:36
  • Hi quick question, how do I delete my hexagon ? – Tim Soph Sep 25 '18 at 19:41
  • You can identify the hexagon as shown in `selectioner`, then use `canvas.delete(hex_id)` – Reblochon Masque Sep 26 '18 at 00:05
  • I see what you mean! Thank you very much! – Tim Soph Sep 26 '18 at 08:03