treasure_hunter_monolith.py

Created by ziii

Created on October 24, 2022

5.79 KB

An adaptation of the mini game “treasure hunter ! monolith” from danganronpa v3 (on mean difficulty). It’s not a perfect reproduction, I implemented only 3 different treasures thanks to the lack of ram on the numworks (I had to perfectly optimize it) and i’m also not sure wich algorithm they use to create the grid, but everything else works as it should.

how to play:

The goal of the game is to find as much treasures as possible to have the best score, at first they’re all hidden under tiles.

There is 4 type of tiles, silver(#1), pink(#2), yellow(#3), blue(#4), and you can remove them if there are tiles of the same types connected (at least 2). Removing them will increment by one the type of every adjacent tiles, the blue tile(#4), will obviously go back to silver(#1). Each tile removed will also give you 5 points.

If you remove all the tiles above a treasure, he will change of color, showing he was discovered. If there is no more connected tiles of the same type the game will stop and tell you there is no more move available.

There is always two “bears” (not really recognizable sorry i’m not good at pixel art) worth 1000 points each and the other 7 treasures are randomly choosen between two types of fishes worth 500 points each, every treasures has a random rotation value.

Ok to interact with tiles.

Arrows to move cursor.

Colors, sprites, hitboxes and scores are fully customisable.

To change colors go to the line 55 and change the rgb values, each line is a different color, changing the rgb values next to #cursor will change the color of the cursor for exemple.

To change the sprites, draw one in my paint program then go to the beginning of the program and change the tuple in the obj_draw variable. The sprite is automatically scaled by a factor of 4, and each tile is 14 pixels long, if the sprite is too big for the hitbox, the parts protuding won’t be drawn on the screen.

To change the hitboxes you’ll have to create by hand a tuple, this tuple should contain tuples with


from random import randrange
from kandinsky import fill_rect as f,draw_string as d
from ion import keydown,KEY_LEFT,KEY_DOWN,KEY_RIGHT,KEY_UP,KEY_OK
from time import monotonic
obj_draw=(
#bear
((6,2,3),(5,3,3),(0,4,14),(0,5,13),(1,6,12),(1,7,12),(0,8,13),(0,9,14),(5,10,3),(6,11,3)),
#straight fish
((1,1,9),(0,2,11),(12,2,2),(0,3,14),(1,4,9),(12,4,2),(3,5,6)),
#diagonal fish
((9,2,3),(8,3,4),(7,4,4),(6,5,5),(5,6,5),(5,7,5),(4,8,5),(4,9,4),(3,10,3),(1,11,4),(2,12,2)),
#comma fish
((8,0,4),(6,1,7),(5,2,8),(4,3,6),(4,4,5),(3,5,4),(3,6,3),(3,7,2),(2,8,3),(3,9,1)))
obj_coo=(
#bear
((1,0),(2,0),(0,1),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(3,2),(1,3),(2,3)),
#straight fish
((0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1)),
#diagonal fish
((2,0),(3,0),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(0,3),(1,3)),
#comma fish
((1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(0,2),(1,2)))
t=lambda coo,r,scale: ((1-r+r%2)*coo[r%2]*scale-(r//2),(1-2*bool(r%3))*coo[(r+1)%2]*scale-bool(r%3))
def square(col):
  f(pos[0]*14,pos[1]*14,15,1,col)
  f(pos[0]*14,(pos[1]+1)*14,15,1,col)
  f(pos[0]*14,pos[1]*14+1,1,13,col)
  f((pos[0]+1)*14,pos[1]*14+1,1,13,col)
def dice_number(x,y):
  f(x*14+1,y*14+1,13,13,COLORS[0][grid[x][y]])
  for a in range(grid[x][y]+1):
    f(x*14+2+7*(a%2),y*14+2+7*(3>a>0),4,4,COLORS[1][grid[x][y]])
def check_no_moves():
  for a in range(0,11*22,2):
    if grid[a//11][a%11]<4 and grid[a//11][a%11] in [grid[c[0]][c[1]] for c in ((a//11+1,a%11),(a//11,a%11+1),(a//11-1,a%11),(a//11,a%11-1)) if (22>c[0]>-1 and 11>c[1]>-1)]:
      return 0
  return 1
def cur(vx=0,vy=0):
  global time, pos
  if monotonic()-time>0.1:
    time=monotonic()
    square(COLORS[3])
    pos[0]=(pos[0]+vx)%22
    pos[1]=(pos[1]+vy)%11
    square(COLORS[4])
def place_obj(id):
  global obj
  rand_coo=(randrange(0,len(grid)),randrange(0,len(grid[0])))
  rand_r=randrange(0,4)
  for c in obj_coo[id]:
    if not (22>rand_coo[0]+t(c,rand_r,1)[0]>-1 and 11>rand_coo[1]+t(c,rand_r,1)[1]>-1):
      return 0
  for o in obj:
    for c in obj_coo[o[0]]:
      for c1 in obj_coo[id]:
        if t(c,o[2],1)[0]+o[1][0]==t(c1,rand_r,1)[0]+rand_coo[0] and (t(c,o[2],1)[1]+o[1][1]==t(c1,rand_r,1)[1]+rand_coo[1]):
          return 0
  obj.append((id,rand_coo,rand_r))
COLORS=(
((192,192,192),#"1" square
(255,182,193),#"2" square
(255,215,0),#"3" square
(0,191,255)),#"4" square
((142,142,142),#"1" number
(205,132,143),#"2" number
(205,165,0),#"3" number
(0,141,205)),#"4" number
(103,75,33),#empty square
(50,50,50),#background
(0,255,0),#cursor
(255,127,0),#text
(133,6,6),#object
(0,10,255))#found object
grid=[[randrange(0,4) for _ in range(11)]for _ in range(22)]
pos=[0,0]
score=0
obj=[]
while len(obj)<2:
  place_obj(0)
while len(obj)<9:
  place_obj(randrange(1,len(obj_coo)))
time=monotonic()
f(0,0,320,222,COLORS[3])
for x in range(22):
  for y in range(11):
    dice_number(x, y)
square(COLORS[4])
run=1
while run:
  if keydown(KEY_LEFT):
    cur(vx=-1)
  elif keydown(KEY_UP):
    cur(vy=-1)
  elif keydown(KEY_DOWN):
    cur(vy=1)
  elif keydown(KEY_RIGHT):
    cur(vx=1)
  elif keydown(KEY_OK):
    if grid[pos[0]][pos[1]]<4 and grid[pos[0]][pos[1]] in [grid[c[0]][c[1]] for c in ((1+pos[0],pos[1]),(pos[0]-1,pos[1]),(pos[0],pos[1]+1),(pos[0],pos[1]-1)) if (len(grid)>c[0]>-1 and len(grid[0])>c[1]>-1)]:
      grid[pos[0]][pos[1]]+=4
      n=grid[pos[0]][pos[1]]
      done=0
      while not done:
        done=1
        for x in range(len(grid)):
          for y in range(len(grid[0])):
            if grid[x][y]==n:
              grid[x][y]=8
              score+=5
              f(x*14+1,y*14+1,14-1,14-1,COLORS[2])
              for c in [[1,0],[0,1],[-1,0],[0,-1]]:
                if len(grid)>x+c[0]>-1 and len(grid[0])>y+c[1]>-1 and grid[x+c[0]][y+c[1]]==n-4:
                  grid[x+c[0]][y+c[1]]=n
                  done=0
      for x in range(len(grid)):
        for y in range(len(grid[0])):
          if 8 in [grid[c[0]][c[1]] for c in ((x+1,y),(x,y+1),(x-1,y),(x,y-1)) if (len(grid)>c[0]>-1 and len(grid[0])>c[1]>-1)] and grid[x][y]<8:
            grid[x][y]=(grid[x][y]+1)%4
            dice_number(x,y)
      for x in range(len(grid)):
        for y in range(len(grid[0])):
          if grid[x][y]==8:
            f(x*14+1,y*14+1,14-1,14-1,COLORS[2])
      for n,o in enumerate(obj):
        found=all([grid[o[1][0]+t(c,o[2],1)[0]][o[1][1]+t(c,o[2],1)[1]]>7 for c in obj_coo[o[0]]])
        if found:
          score+=500+500*(not o[0])
          obj[n]=0
        for c in obj_coo[o[0]]:
          if grid[o[1][0]+t(c,o[2],1)[0]][o[1][1]+t(c,o[2],1)[1]]==8 or (grid[o[1][0]+t(c,o[2],1)[0]][o[1][1]+t(c,o[2],1)[1]]==9 and found):
            r=o[2]
            a=r%2
            cor=((o[1][0]+t(c,r,1)[0])*14+1,(o[1][1]+t(c,r,1)[1])*14+1)
            coo=(o[1][0]*14,o[1][1]*14)
            if cor[not a]+19>=coo[not a]+t(obj_draw[o[0]][-(r//2)],r,4)[not a] and coo[not a]+t(obj_draw[o[0]][(r-2)//2],r,4)[not a]>=cor[not a]:
              for l in obj_draw[o[0]]:
                for s in range(4):
                  if 13>coo[not a]+t(l,r,4)[not a]+s-cor[not a]>=0 and cor[a]+13>coo[a]+t(l,r,4)[a]-l[2]*(bool(r%3))*4 and coo[a]+t(l,r,4)[a]+l[2]*(not r%3)*4>cor[a]:
                      sq=[coo[0]+t(l,r,4)[0]-l[2]*(r==2)*4+s*a,coo[1]+t(l,r,4)[1]-l[2]*(r==1)*4+s*(not a),coo[0]+t(l,r,4)[0]+l[2]*(r==0)*4+s*a,coo[1]+t(l,r,4)[1]+l[2]*(r==3)*4+s*(not a)]
                      sq[a]=(sq[a],cor[a])[cor[a]>sq[a]]
                      sq[a+2]=(sq[a+2],cor[a]+13)[sq[a+2]>cor[a]+13]
                      f(sq[0],sq[1],(sq[2]-sq[0])**(not a),(sq[3]-sq[1])**a,COLORS[6+found])
      obj=[o for o in obj if o]
      for x in range(len(grid)):
        for y in range(len(grid[0])):
          if grid[x][y]==8:
            grid[x][y]=9
      d("SCORE: {}".format(score),0,200,COLORS[5],COLORS[3])
    if check_no_moves():
      square(COLORS[3])
      d("NO MORE MOVES",100,180,COLORS[5],COLORS[3])
      run=0