2024-08-05 13:41:50 -04:00
from collections import OrderedDict
from PIL import Image , ImageChops , ImageDraw
import time
import json
import os
import os . path
try :
import pymongo
except :
pass
import math
try :
from bson . objectid import ObjectId
except :
pass
from image_util import load_image , image_to_string_format , \
reduce_to_colors
try :
conn = pymongo . Connection ( ' localhost ' )
db = conn . ztrans
except :
pass
def replace_color ( im , color1 , color2 ) :
mode = im . mode
im = im . convert ( " P " , palette = Image . ADAPTIVE )
p = im . getpalette ( )
new_p = list ( )
for i in range ( 256 ) :
r = p [ 3 * i ]
g = p [ 3 * i + 1 ]
b = p [ 3 * i + 2 ]
if r == color1 [ 0 ] and g == color1 [ 1 ] and b == color1 [ 2 ] :
new_p . extend ( color2 [ : 3 ] )
else :
new_p . extend ( [ r , g , b ] )
im . putpalette ( new_p )
return im . convert ( mode )
class TileSetParser :
@classmethod
def parse_images ( cls , image_list , seed_list , seed_fails , tilesize ) :
x = None
y = None
tiles = OrderedDict ( )
fail_tiles = OrderedDict ( )
seed_tiles = OrderedDict ( )
for ii , im in enumerate ( seed_list ) :
#print(ii, len(seed_list))
if x is None :
x , y = TileTools . find_tileset_offset ( im , tilesize )
these_tiles = TileTools . get_tiles ( im , x , y , tilesize )
for t in these_tiles :
seed_tiles [ t ] = seed_tiles . get ( t , 0 ) + these_tiles [ t ]
for im in seed_fails :
these_tiles = TileTools . get_tiles ( im , x , y , tilesize )
for t in these_tiles :
fail_tiles [ t ] = fail_tiles . get ( t , 0 ) + these_tiles [ t ]
maps = 0
for ii , image in enumerate ( image_list ) :
#print("tt--", ii)
these_tiles = TileTools . get_tiles ( image , x , y , tilesize )
c = 0
for t in these_tiles :
if t in fail_tiles :
c + = these_tiles [ t ]
for t in these_tiles :
if t in fail_tiles and c > 10 :
for s in these_tiles :
if s not in tiles :
fail_tiles [ s ] = 1
break
else :
print ( " succ " )
#test for success tiles...
succ = 0
ox , oy = TileTools . find_tileset_offset ( image , tilesize )
if ox == x and oy == y :
image . save ( " maps_ " + str ( maps ) + " .png " )
maps + = 1
for s in these_tiles :
tiles [ s ] = tiles . get ( s , 0 ) + these_tiles [ s ]
width = 16 * tilesize
height = int ( len ( tiles ) / tilesize + 1 ) * tilesize
nim = Image . new ( " RGB " , ( width , height ) )
wx = 0
wy = 0
for key in tiles :
subi = load_image ( key )
draw = ImageDraw . Draw ( subi )
draw . line ( ( 0 , 0 , subi . width , 0 ) , fill = 128 )
draw . line ( ( 0 , 0 , 0 , subi . height ) , fill = 128 )
nim . paste ( subi , ( wx , wy ) )
wx + = tilesize
if wx > = width :
wx = 0
wy + = tilesize
nim . save ( " t.png " )
#import pdb
#pdb.set_trace()
return { " tileset " : nim , " tiles " : tiles , " fail_tiles " : fail_tiles ,
" off_x " : x , " off_y " : y , " tilesize " : tilesize }
def main ( ) :
start_image_id = ObjectId ( " 5df9d8208ac3d956387c0941 " )
doc = db . ocr_images . find_one ( { " _id " : start_image_id } )
game_id = doc [ ' game_id ' ]
user_id = doc [ ' user_id ' ]
seed_list_ids = [ ObjectId ( " 5df9d8df8ac3d956387c0957 " ) ,
ObjectId ( " 5df9d9008ac3d956387c095d " ) ,
]
seed_fail_ids = [ ]
seed_list = list ( )
fail_list = list ( )
for seed_id in seed_list_ids :
doc = db . ocr_images . find_one ( { " _id " : seed_id } )
img = load_image ( doc [ ' image_data ' ] )
seed_list . append ( img )
for fail_id in seed_fail_ids :
doc = db . ocr_images . find_one ( { " _id " : fail_id } )
img = load_image ( doc [ ' image_data ' ] )
fail_list . append ( img )
image_list = [ Image . open ( " text " + str ( i ) + " .png " ) for i in range ( 7 ) ]
f = ParseScreenText . get_font ( image_list )
start_image_id = ObjectId ( " 5df9d8208ac3d956387c0941 " )
doc = db . ocr_images . find_one ( { " _id " : start_image_id } )
game_id = doc [ ' game_id ' ]
user_id = doc [ ' user_id ' ]
image_list = list ( )
c = 0
for image in db . ocr_images . find ( { " user_id " : user_id ,
" game_id " : game_id } ,
sort = [ ( " _id " , pymongo . ASCENDING ) ] ) :
im = load_image ( image [ ' image_data ' ] )
tex = ParseScreenText . parse_screen ( im , f )
c + = 1
if image [ ' _id ' ] in [ ObjectId ( ' 5e3e44e48ac3d94113fa1361 ' ) ,
ObjectId ( ' 5e3e44e68ac3d94112f910c6 ' ) ,
ObjectId ( ' 5e3e44e88ac3d94113fa1363 ' ) ,
ObjectId ( ' 5e3e44ff8ac3d94113fa1366 ' ) ] :
im . paste ( im . crop ( ( 0 , 0 , 160 , im . height ) ) , ( 32 , 0 ) )
if not tex :
image_list . append ( im )
res = TileSetParser . parse_images ( image_list , seed_list , fail_list ,
tilesize = 16 )
ts = [ " grass " , " woods " , " wall " , " castle " , " water " ,
" town " , " port " , " building " , " inn " , " tree " ,
" path " , " door " , " fence " , " armor shop " , " weapon shop " ,
" foutain " , " well " , " bridge " , " item shop " , " clinic " ,
" swamp " , " rock " , " ruins " , " black magic shop " , " white magic shop " ,
" tile " , " stairs up " , " column " , " statue " , " fireplace " ,
" chair " , " table " , " bed " , " stairs down " , " throne " ,
" chest " , " orb " , " cave " , " skull " , " vase " ,
" desert " , " ship " , " river " , " meadow " , " tombstone " ,
" ladder down " , " ladder up " , " dirt " , " hammer " , " sword " ,
" anvil " , " lid " , " alter " , " exit " , " hole " ,
" poison " , " candles " , " volcano " , " fairy " , " submarine " ,
" tower " , " computer " , " runes " , " teleporter up " , " teleporter down " ,
" fire " , " door " , " king "
]
res [ ' tileset ' ] . save ( " tileset__.png " )
res [ ' tileset ' ] . show ( )
import pdb
pdb . set_trace ( )
sounds = [ ]
obss = [ 0 , 0 , 1 , 2 , 1 ,
2 , 2 , 1 , 3 , 1 ,
0 , 0 , 1 , 3 , 3 ,
1 , 1 , 2 , 3 , 3 ,
0 , 1 , 2 , 3 , 3 ,
0 , 2 , 1 , 1 , 1 ,
0 , 1 , 1 , 2 , 1 ,
2 , 3 , 2 , 0 , 1 ,
0 , 2 , 1 , 0 , 1 ,
2 , 2 , 0 , 1 , 1 ,
1 , 3 , 1 , 2 , 2 ,
0 , 1 , 2 , 3 , 2 ,
2 , 1 , 1 , 2 , 2 ,
1 , 3 , 3
] #0-no obs, 1-obst, 2-no obst special, 3-special obst
mapp = [ 1 , 1 , 1 , 0 , 2 , 3 , 3 , 3 , 2 , 2 , 4 , 2 , 5 , 0 , 2 , 2 ,
2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 1 , 1 , 1 , 1 , 0 , 4 , 0 , 6 ,
6 , 6 , 4 , 4 , 6 , 6 , 2 , 2 , 2 , 2 , 2 , 2 , 7 , 8 , 0 , 9 ,
10 , 0 , 4 , 2 , 11 , 0 , 12 , - 1 , 10 , - 1 , 9 , 2 , 2 , 2 , 7 , - 1 ,
- 1 , 7 , - 1 , - 1 , 10 , 2 , 2 , 13 , 14 , 10 , - 1 , - 1 , - 1 , - 1 , 15 , 0 ,
- 1 , - 1 , - 1 , - 1 , - 1 , 16 , 7 , - 1 , - 1 , 17 , - 1 , 18 , 4 , - 1 , 4 , 17 ,
7 , 19 , - 1 , - 1 , - 1 , - 1 , 0 , 1 , 0 , 4 , 20 , 20 , 20 , 21 , 21 , 21 ,
21 , 21 , 20 , 20 , 21 , 21 , 22 , 22 , 0 , 22 , 22 , 0 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 23 , 24 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 25 , - 1 , 2 , 2 , 0 , 2 , 26 , 27 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 11 , - 1 , 2 , - 1 , 2 , 2 , 2 , 2 ,
28 , 29 , 28 , 2 , 30 , 31 , 30 , - 1 , 31 , - 1 , 25 , 2 , 25 , 2 , 11 , 32 ,
- 1 , 2 , - 1 , - 1 , 25 , - 1 , 2 , 33 , 34 , 34 , 34 , 34 , 67 , 34 , 25 , 2 ,
66 , 27 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 25 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 11 , 35 , 28 , - 1 , - 1 , - 1 ,
25 , 28 , - 1 , - 1 , - 1 , 28 , - 1 , 25 , 2 , - 1 , 2 , - 1 , 27 , 2 , 26 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 36 , 2 , - 1 , - 1 , - 1 , - 1 ,
17 , 4 , 4 , 21 , 21 , 37 , 2 , 2 , 2 , 2 , 2 , 2 , 26 , 2 , 11 , 25 ,
2 , 2 , 2 , 2 , - 1 , - 1 , 38 , - 1 , - 1 , 25 , 2 , 2 , 2 , 2 , - 1 , 2 ,
11 , 2 , - 1 , 39 , - 1 , - 1 , 31 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 0 ,
40 , 0 , 0 , 0 , 2 , 5 , 2 , 2 , 10 , - 1 , 10 , - 1 , 2 , 2 , 2 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , 41 , 42 , 42 , 43 , 43 , 43 , 43 , 3 , 3 , 43 , 5 , 3 ,
3 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 28 , 32 , - 1 ,
- 1 , 44 , 42 , 54 , - 1 , 25 , 27 , 26 , 25 , - 1 , 25 , 25 , - 1 , 25 , 2 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 66 , 25 , 27 , 2 , 2 , 2 , 2 , 2 ,
46 , 2 , 25 , 2 , 2 , 11 , 27 , 33 , 35 , 26 , 47 , 11 , - 1 , 2 , 2 , 2 ,
25 , 2 , 2 , 2 , 2 , 2 , 2 , 27 , 25 , 26 , 2 , 2 , 2 , 2 , 2 , 2 ,
25 , 2 , 2 , 11 , 11 , - 1 , - 1 , 25 , 25 , 27 , 25 , - 1 , 28 , - 1 , 25 , 25 ,
- 1 , - 1 , - 1 , 25 , - 1 , - 1 , 34 , - 1 , 35 , 34 , 34 , - 1 , - 1 , - 1 , - 1 , - 1 ,
2 , - 1 , 2 , 2 , 2 , - 1 , - 1 , 28 , - 1 , 30 , - 1 , 30 , 31 , - 1 , 30 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 0 , 47 , 21 ,
2 , 2 , 2 , - 1 , 2 , - 1 , - 1 , - 1 , 2 , 2 , 2 , 2 , 2 , 2 , - 1 , - 1 ,
- 1 , - 1 , 21 , 2 , 2 , 2 , 2 , - 1 , 2 , - 1 , 30 , 2 , 25 , 2 , 2 , - 1 ,
- 1 , 29 , 48 , 49 , 50 , 5 , 0 , 40 , 10 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 40 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , 21 , 47 , 26 , 2 , 2 , 2 , 2 , 2 , 47 , - 1 , - 1 , 47 , 21 , 47 , 2 ,
2 , 2 , 2 , 2 , 2 , 25 , 2 , 2 , 11 , 11 , 47 , - 1 , - 1 , - 1 , - 1 , 47 ,
- 1 , 2 , 2 , 2 , 2 , 33 , 2 , 47 , 47 , - 1 , - 1 , 2 , 2 , 2 , 2 , 2 ,
2 , 2 , 2 , 2 , - 1 , 47 , - 1 , - 1 , - 1 , - 1 , 2 , 2 , - 1 , 2 , 26 , 21 ,
- 1 , 51 , 47 , 21 , - 1 , 47 , 26 , 2 , 2 , 2 , 2 , 2 , 2 , - 1 , 47 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 25 , 2 , 2 , 2 , 2 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 29 , 32 , - 1 , 32 , - 1 , 2 ,
2 , 2 , 2 , 35 , 2 , 2 , 2 , - 1 , 2 , 2 , 25 , 2 , 2 , 2 , 35 , 47 ,
47 , 47 , 47 , 47 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 2 , 2 , 2 ,
2 , 2 , 2 , 52 , 2 , - 1 , 36 , 2 , 53 , 5 , 0 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 2 , 2 , 2 , 47 , 21 , 33 , 2 , 2 , 2 , 2 ,
2 , 2 , 2 , 2 , 54 , 2 , 21 , 2 , 2 , 2 , 2 , 25 , 2 , 2 , 2 , 2 ,
2 , 55 , 2 , 2 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , 47 , 2 , 2 , 2 , 2 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 47 , 2 , 2 , 2 , 2 , - 1 ,
2 , - 1 , 2 , 25 , 2 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 2 , 2 , 2 ,
2 , - 1 , - 1 , - 1 , - 1 , 16 , - 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,
2 , 2 , 25 , 2 , 2 , 2 , 2 , 56 , - 1 , - 1 , 2 , 2 , 2 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 10 , - 1 , - 1 , - 1 , - 1 ,
- 1 , 9 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , 9 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , 9 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 2 , 2 ,
47 , 2 , 47 , 47 , 47 , - 1 , - 1 , - 1 , - 1 , - 1 , 57 , 57 , 57 , 57 , 21 , 21 ,
47 , 55 , 26 , 33 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,
2 , 2 , 2 , 2 , 25 , 2 , 2 , 2 , 2 , 47 , 55 , 26 , 2 , 2 , 2 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 33 , 21 , 21 , 2 , 2 , 2 , 47 , 47 ,
2 , 2 , 2 , 2 , 25 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , - 1 , 36 , 2 , 2 ,
2 , 2 , 2 , 2 , 2 , 2 , 53 , 2 , 2 , 52 , 2 , 25 , 2 , 2 , 2 , 11 ,
- 1 , - 1 , - 1 , - 1 , 58 , 59 , 2 , 2 , 25 , 2 , 2 , 2 , 4 , 59 , 2 , 2 ,
2 , 2 , 2 , 27 , 2 , 2 , 66 , 47 , 47 , 2 , 2 , 2 , 2 , 35 , 2 , 2 ,
25 , 2 , 2 , 11 , 33 , 26 , 4 , 25 , 33 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,
2 , 2 , 2 , 66 , 2 , 2 , 2 , 2 , 2 , 2 , 25 , 2 , 11 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 2 , 2 , 2 , 2 , 66 , 2 , 26 ,
33 , 53 , 2 , 52 , 2 , 28 , - 1 , 28 , 36 , 10 , - 1 , - 1 , 10 , - 1 , - 1 , 10 ,
- 1 , - 1 , - 1 , 60 , 60 , 40 , 2 , 2 , 2 , 2 , 25 , 66 , 2 , 2 , 2 , 2 ,
26 , 33 , 27 , 25 , 2 , 2 , 11 , 2 , 2 , 11 , 2 , 2 , 2 , 26 , 33 , 2 ,
2 , 2 , 61 , 61 , - 1 , - 1 , - 1 , 2 , 2 , 27 , 2 , - 1 , - 1 , 2 , 2 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , 2 , 27 , 61 , 2 , 61 , 2 , 2 , 2 , 2 , 25 , 33 ,
2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 66 , 2 , 2 , 28 , 2 , 62 , 2 ,
2 , - 1 , 2 , 25 , 25 , 2 , 2 , 25 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ,
62 , 2 , 2 , 25 , 66 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 35 , 11 , 63 ,
64 , - 1 , - 1 , - 1 , 61 , 61 , 30 , 61 , 62 , 2 , 52 , 2 , - 1 , 36 , 53 , 36 ,
- 1 , - 1 , 66 , 28 , 36 , - 1 , - 1 , - 1 , 28 , - 1 , - 1 , - 1 , - 1 , 25 , 27 , 2 ,
2 , 2 , 2 , 2 , 2 , 25 , 2 , 2 , 2 , 2 , 2 , 27 , 2 , 52 , 2 , 53 ,
45 , 53 , 51 , 26 , 46 , 2 , 2 , 2 , 62 , 11 , 2 , 2 , 65 , 65 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 26 , 41 , 41 , 41
]
lud = dict ( )
person_dict = dict ( )
person_box = ( 6 , 5 , 10 , 11 )
person_tiles = list ( )
fail_person_tiles = list ( )
fail_person_dict = dict ( )
for i , key in enumerate ( res [ ' tiles ' ] ) :
if i > = len ( mapp ) :
continue
elif mapp [ i ] > = 0 :
num = mapp [ i ]
typ = ts [ num ]
obs = obss [ num ]
subi = load_image ( key )
subi_key = image_to_string_format ( subi , " BMP " )
lud [ subi_key ] = { " type " : typ , " obs " : obs , " num " : num , " raw_i " : i }
elif mapp [ i ] == - 1 :
#this is a person tile, so put it into the person-sets.
#go through all (regular) tiles and find the one with the lowest
#difference with this tile.
max_c = 0
succ_tile = None
diff_tile = None
for j , tile in enumerate ( res [ ' tiles ' ] ) :
if j < len ( mapp ) and mapp [ j ] > = 0 :
dd = ImageChops . difference ( load_image ( key ) , load_image ( tile ) )
for c in dd . convert ( " RGBA " ) . getcolors ( ) :
if c [ 1 ] [ : 3 ] == ( 0 , 0 , 0 ) :
val = c [ 0 ]
if val > max_c :
max_c = val
succ_tile = tile
diff_tile = dd
if succ_tile :
cropped1 = load_image ( succ_tile ) . crop ( person_box )
cropped2 = load_image ( key ) . crop ( person_box )
dd = ImageChops . difference ( cropped1 , cropped2 ) . convert ( " RGBA " )
cc = None
for cc in dd . getcolors ( ) :
if cc [ 1 ] [ : 3 ] == ( 0 , 0 , 0 ) :
break
if ( cc and cc [ 0 ] < cropped1 . width * cropped1 . height / 2 ) or cc is None :
if cc :
print ( [ cc [ 0 ] , 64 ] )
pkey = image_to_string_format ( cropped2 , " BMP " )
person_dict [ key ] = pkey
person_tiles . append ( key )
else :
pkey = image_to_string_format ( cropped2 , " BMP " )
fail_person_tiles . append ( key )
fail_person_dict [ key ] = pkey
#...a
tilesize = 16
width = 8 * tilesize
height = int ( len ( person_tiles ) / 8 + 1 ) * tilesize
pim = Image . new ( " RGB " , ( width , height ) )
wx = 0
wy = 0
for key in person_tiles :
subi = load_image ( key ) . crop ( ( 0 , 0 , tilesize - 1 , tilesize - 1 ) )
pim . paste ( subi , ( wx , wy ) )
wx + = tilesize
if wx > = width :
wx = 0
wy + = tilesize
pim . save ( " p.png " )
pim . show ( )
wx = 0
wy = 0
width = 8 * tilesize
height = int ( len ( fail_person_tiles ) / 8 + 1 ) * tilesize
pim2 = Image . new ( " RGB " , ( width , height ) )
for key in fail_person_tiles :
subi = load_image ( key ) . crop ( ( 0 , 0 , tilesize - 1 , tilesize - 1 ) )
pim2 . paste ( subi , ( wx , wy ) )
wx + = tilesize
if wx > = width :
wx = 0
wy + = tilesize
pim2 . save ( " p_f.png " )
pim2 . show ( )
#fix p.png stuff here below--v !!!
pmap = [ 0 , 0 , 0 , 1 , 1 , 2 , 1 , 0 ,
3 , 0 , 2 , 0 , 2 , 2 , 2 , 1 ,
2 , 1 , 2 , 2 , 1 , 1 , 2 , 4 ,
1 , 5 , 4 , 5 , 4 , 4 , 1 , 0 ,
3 , 3 , 0 , 3 , 0 , 3 , 0 , 3 ,
6 , 6 , 7 , 0 , 6 , 6 , 6 , 6 ,
6 , 10 , 10 , 10 , 11 , 10 , 10 , 11 ,
10 , 10 , 12 , 12 , 12 , 12 , 13 , 13 ,
13 , 13 , 0 , 13 , 0 , 12 , 0 , 12 ,
0 , 5 , 5 , 5 , 13 , 5 , 13 , 14 ,
14 , 14 , 14 , 14 , 14 , 14 , 14 , 14 ,
10 , 10 , 10 , 14 , 6 , 6 , 6 , 6 ,
5 , 1 , 5 , 7 , 0 , 7 , 0 , 16 ,
16 , 16 , 16 , 16 , 16 , 16 , 12 , 12 ,
12 , 12 , 12 , 0 , 12 , 12 , 12 , 16 ,
12 , 5 , 16 , 5 , 16 , 16 , 0 , 16 ,
7 , 7 , 12 , 7 , 12 , 7 , 17 , 18 ,
18 , 5 , 5 , 0 , 0 , 0 , 0 , 12 ,
12 , 19 , 19 , 19 , 20 , 20 , 20 , 20 ,
20 , 20 , 20 , 20 , 20 , 12 , 12 , 12 ,
12 , 7 , 2 , 7 , 7 , 2 , 7 , 2 ,
7 , 7 , 10 , 2 , 2 , 10 , 10 , 10 ,
11 , 10 , 11 , 10 , 2 , 2 , 2 , 4 ,
4 , 12 , 4 , 4 , 4 , 0 , 0 , 0 ,
4 , 0 , 21 , 21 , 21 , 2 , 13 , 2 ,
2 , 13 , 13 , 1 , 13 , 1 , 1 , 2 ,
2 , 13 , 21 , 21 , 13 , 13 , 12 , 21 ,
12 , 21 , 5 , 1 , 2 , 5 , 2 , 11 ,
11 , 0 , 0 , 0 , 0 , 0 , 0 , 20 ,
20 , 20 , 22 , 22 , 19 , 19 , 19 , 23 ,
23 , 23 , 23 , 23 , 24 , 24 , 24 , 24 ,
24 , 22 , 22 , 22 , 25 , 25 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1
]
pmapf = [ - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
1 , - 1 , - 1 , - 1 , - 1 , - 1 , 25 , 25 ,
- 1 , - 1 , - 1 , 9 , 25 , - 1 , 25 , 25 ,
25 , - 1 , 9 , - 1 , 25 , 25 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 13 , - 1 ,
13 , - 1 , 13 , - 1 , 21 , - 1 , - 1 , - 1 ,
- 1 , 21 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 25 , 25 ,
- 1 , - 1 , - 1 , - 1 , 25 , 25 , 25 , - 1 ,
25 , 25 , - 1 , 15 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 12 ,
- 1 , 0 , 12 , - 1 , - 1 , - 1 , 0 , - 1 ,
0 , - 1 , 0 , - 1 , - 1 , 0 , - 1 , - 1 ,
12 , - 1 , - 1 , 12 , - 1 , - 1 , - 1 , - 1 ,
0 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , 16 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , 16 , - 1 , - 1 ,
- 1 , - 1 , 25 , - 1 , - 1 , - 1 , - 1 , 25 ,
- 1 , - 1 , - 1 , 25 , - 1 , 25 , - 1 , 25 ,
- 1 , 25 , 25 , - 1 , 25 , 25 , 25 , - 1 ,
25 , - 1 , 25 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , 19 , 19 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
2 , - 1 , - 1 , - 1 , - 1 , 2 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 0 ,
- 1 , - 1 , 21 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , 21 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 20 ,
- 1 , - 1 , - 1 , 25 , 25 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , 22 , 22 , - 1 , - 1 , - 1 ,
22 , - 1 , - 1 , - 1 , 22 , 22 , - 1 , - 1 ,
25 , - 1 , - 1 , - 1 , - 1 , 25 , - 1 , 9 ,
9 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
- 1
]
persons = [ " woman " , " guard " , " dancer " , " boy " , " old woman " ,
" old man " , " girl " , " scholar " , " king " , " garland " ,
" broom " , " witch " , " man " , " punk " , " elf " ,
" astros " , " dwarf " , " vampire " , " monster " , " airship " ,
" dragon " , " pirate " , " robot " , " mermaid " , " robed " ,
" bat " ,
]
plud = { " person_box " : person_box ,
" person_dict " : { } }
for i , key in enumerate ( person_tiles ) :
2024-08-06 12:41:40 -04:00
print ( ( " p " , i , key ) )
2024-08-05 13:41:50 -04:00
if pmap [ i ] > = 0 :
cropped_pic = person_dict [ key ]
plud [ ' person_dict ' ] [ cropped_pic ] = {
" num " : pmap [ i ] ,
" type " : persons [ pmap [ i ] ] ,
" obs " : 1 ,
" raw_i " : i
}
for i , key in enumerate ( fail_person_tiles ) :
2024-08-06 12:41:40 -04:00
print ( ( " pp " , i , key ) )
2024-08-05 13:41:50 -04:00
if pmapf [ i ] > = 0 :
cropped_pic = fail_person_dict [ key ]
plud [ ' person_dict ' ] [ cropped_pic ] = {
" num " : pmapf [ i ] ,
" type " : persons [ pmapf [ i ] ] ,
" obs " : 1 ,
" raw_i " : i ,
" fail_set " : True ,
}
tile_info = { " off_x " : res [ ' off_x ' ] ,
" off_y " : res [ ' off_y ' ] ,
" tilesize " : res [ ' tilesize ' ]
}
saved_data = { " tile_info " : tile_info , " lud " : lud ,
" plud " : plud }
file_w = open ( " ff1_data.lud " , " w " )
file_w . write ( json . dumps ( saved_data ) )
for i in range ( 10 ) :
im = Image . open ( " maps_ " + str ( 2 + i ) + " .png " )
t = time . time ( )
k , map_data = ParseScreenObstructions . parse_screen ( im , tile_info , lud ,
plud , partial_center = True )
2024-08-06 12:41:40 -04:00
print ( ( time . time ( ) - t ) )
2024-08-05 13:41:50 -04:00
import pdb
pdb . set_trace ( )
class PathFinder :
persons_set = { " woman " , " guard " , " dancer " , " boy " , " old woman " ,
" old man " , " girl " , " scholar " , " king " , " garland " ,
" broom " , " witch " , " man " , " punk " , " elf " ,
" astros " , " dwarf " , " vampire " , " monster " , " airship " ,
" dragon " , " pirate " , " robot " , " mermaid " , " robed " }
dont_expand_types = [ ' stairs up ' , ' stairs down ' , ' ladder up ' , ' ladder down ' , " teleporter up " , " teleporter down " , " hole " ]
@classmethod
def find_paths ( cls , map_data , y , x ) :
def valid ( y , x ) :
if map_data [ ' tiles ' ] [ y ] [ x ] [ ' obs ' ] in ob or map_data [ ' tiles ' ] [ y ] [ x ] [ ' type ' ] in cls . persons_set :
return True
return False
def dont_expand ( y , x ) :
if map_data [ ' tiles ' ] [ y ] [ x ] [ ' obs ' ] in obs or map_data [ ' tiles ' ] [ y ] [ x ] [ ' type ' ] in cls . persons_set or map_data [ ' tiles ' ] [ y ] [ x ] [ ' type ' ] in cls . dont_expand_types :
return True
return False
marked = { ( y , x ) : ( 0 , 0 ) }
last_marked = [ ( y , x ) ]
ob = [ 0 , 2 , 3 ]
obs = [ 3 ]
print ( map_data )
try :
while last_marked :
new_marked = list ( )
for y , x in last_marked :
if map_data [ ' tiles ' ] [ y ] [ x ] and dont_expand ( y , x ) :
continue
#mark up
if y > 0 and ( y - 1 , x ) not in marked and valid ( y - 1 , x ) :
new_marked . append ( ( y - 1 , x , 1 , 0 ) )
marked [ ( y - 1 , x ) ] = ( - 1 , 0 )
#mark down
if y < len ( map_data [ ' tiles ' ] ) - 1 and ( y + 1 , x ) not in marked and valid ( y + 1 , x ) :
new_marked . append ( ( y + 1 , x , - 1 , 0 ) )
marked [ ( y + 1 , x ) ] = ( 1 , 0 )
#mark left
if x > 0 and ( y , x - 1 ) not in marked and valid ( y , x - 1 ) :
new_marked . append ( ( y , x - 1 , 0 , 1 ) )
marked [ ( y , x - 1 ) ] = ( 0 , - 1 )
#mark right
if x < len ( map_data [ ' tiles ' ] [ 0 ] ) - 1 and ( y , x + 1 ) not in marked and valid ( y , x + 1 ) :
new_marked . append ( ( y , x + 1 , 0 , - 1 ) )
marked [ ( y , x + 1 ) ] = ( 0 , 1 )
last_marked = list ( )
for y , x , vy , vx in new_marked :
last_marked . append ( ( y , x ) )
except :
return None
return marked
@classmethod
def find_path ( cls , marked , y , x ) :
if not ( y , x ) in marked :
return None
path = list ( )
py , px = y , x
while marked [ ( py , px ) ] not in [ ( 0 , 0 ) , None ] :
vy , vx = marked [ ( py , px ) ]
path . append ( ( py , px , vy , vx ) )
py - = vy
px - = vx
2024-08-06 12:41:40 -04:00
print ( ( " path " , path [ - 1 ] ) )
2024-08-05 13:41:50 -04:00
path = path [ : : - 1 ]
return path
class PackageOutput :
def __init__ ( self , filename , enemy_filename ) :
ScreenSelector . _load_content ( None , None , None , filename , enemy_filename )
self . memory = list ( )
self . pause_mode = { " active " : False , " goal " : None }
self . press_mem = { }
self . state_mem = { }
def get_output ( self , im , state_dict ) :
typ , k , map_data = ScreenSelector . parse_whole_screen ( im )
path_data = PathFinder . find_paths ( map_data , 6 , 7 )
#for key in state_dict:
# if key in ['up', 'down', 'left', 'right'] and state_dict.get(key) == 1:
# self.pause_mode['active'] = False
# self.pause_mode['goal'] = 'menu'
#print(k)
#print(typ, '-----')
mem = self . memory
if self . state_mem . get ( ' paused ' ) != state_dict . get ( " paused " ) :
mem = dict ( )
output = list ( )
press_output = list ( )
mem_dont = False
if typ == " world " :
if state_dict . get ( " paused " ) == 0 or True :
if not k :
mem_dont = True
for entry in k :
#if entry not in mem:
output . append ( entry )
else :
#maybe not?
for entry in k :
output . append ( entry )
elif typ == ' map ' :
#print(state_dict)
specials = dict ( )
specials_list = list ( )
if state_dict . get ( ' paused ' ) == 0 :
special_flag = False
for entry in k :
if entry == " special " :
special_flag = True
elif special_flag :
sp = entry . split ( " " )
spec = sp [ 0 ]
for i in range ( len ( sp ) ) :
if sp [ i ] . replace ( " - " , " " ) . isdigit ( ) :
spec = " " . join ( sp [ : i ] )
break
if spec not in " " . join ( mem ) :
2024-08-06 12:41:40 -04:00
print ( ( " spec " , spec ) )
print ( ( " " . join ( mem ) . split ( ) ) )
2024-08-05 13:41:50 -04:00
specials [ spec ] = 1
else :
sp = entry . split ( " " )
if len ( sp ) > 3 :
sp [ 2 ] = " " . join ( sp [ 2 : ] )
if len ( sp ) > 2 and sp [ 2 ] in [ ' grass ' , ' woods ' ,
' dirt ' , ' desert ' ,
' swamp ' , ' tile ' , ' meadow ' ] :
continue
output . append ( sp [ 0 ] + " " + sp [ 2 ] + " , " )
if not output :
output . append ( " None " )
if specials :
2024-08-06 12:41:40 -04:00
print ( ( " ____++ " , mem ) )
2024-08-05 13:41:50 -04:00
output . append ( " special, " )
for key in specials :
output . append ( key + " , " )
if output and output [ - 1 ] and output [ - 1 ] [ - 1 ] == " , " :
output [ - 1 ] = output [ - 1 ] [ : - 1 ]
for key in [ ' west ' , ' east ' , ' south ' , ' north ' ] :
if key + " unknown " not in output and \
key + " unknown, " not in output :
break
else :
output = [ " " ]
mem_dont = True
else :
special = False
dir_seen = dict ( )
mem_seen = dict ( )
try :
mem [ 5 : ]
except :
mem = list ( )
for entry in k :
if special is False and entry . split ( " " ) [ 0 ] . lower ( ) in [ ' west ' , ' east ' , ' north ' , ' south ' ] :
output . append ( entry + " , " )
elif entry == ' special ' :
special = True
output . append ( entry + " , " )
else :
#for the ai menu...
specials_list . append ( entry )
sp = entry . split ( " " )
seen = [ ]
#convert from coordinates here to west/east directions
count = 0
res = list ( )
for i , ent in enumerate ( sp ) :
if ent . replace ( " - " , " " ) . isdigit ( ) :
if count == 0 :
if int ( ent ) > 0 :
res . append ( " east " + ent )
else :
res . append ( " west " + ent . replace ( " - " , " " ) )
count + = 1
else :
if int ( ent ) > 0 :
res . append ( " north " + ent )
else :
res . append ( " south " + ent . replace ( " - " , " " ) )
else :
res . append ( ent )
entry = " " . join ( res )
if entry not in mem_seen :
seen . append ( entry )
if len ( seen ) > 0 :
output . append ( " " . join ( seen ) + " , " )
if output [ - 1 ] in [ ' special ' , ' special, ' ] :
output = output [ : - 1 ]
if output and output [ - 1 ] and output [ - 1 ] [ - 1 ] == " , " :
output [ - 1 ] = output [ - 1 ] [ : - 1 ]
elif typ == ' text ' :
for entry in k :
if entry not in mem :
output . append ( entry )
elif typ == ' menu ' :
for entry in k :
if entry not in mem :
output . append ( entry )
elif typ == ' shop ' :
if type ( k ) != type ( mem ) :
output = [ k [ ' title ' ] , k [ ' text ' ] , k [ ' menu ' ] ]
else :
output = list ( )
for key in [ ' title ' , ' text ' , ' menu ' ] :
if mem . get ( key ) != k [ key ] :
output . append ( k [ key ] )
elif typ == ' battle ' :
output = list ( )
if state_dict . get ( " paused " , 0 ) == 0 :
for key in [ ' enemy_string ' , ' status ' , ' character ' , ' menu ' ] :
if key == " status " :
if type ( k ) != type ( mem ) and k [ key ] :
output . extend ( k [ key ] )
elif k [ key ] :
for entry in k [ key ] :
if entry not in mem . get ( key , [ ] ) :
output . append ( entry )
elif ( type ( k ) != type ( mem ) or mem . get ( key ) != k . get ( key ) ) and k . get ( key ) :
if type ( k [ key ] ) == list :
output . extend ( k [ key ] )
else :
output . append ( k [ key ] )
else :
for key in [ ' enemy_string ' , ' status ' , ' textbox ' , ' character ' , ' menu ' ] :
if k [ key ] :
if type ( k [ key ] ) == list :
output . extend ( k [ key ] )
else :
output . append ( k [ key ] )
if mem_dont == False :
self . memory = k
self . state_mem = state_dict
clicked = dict ( )
for key in state_dict :
if state_dict [ key ] and not self . press_mem . get ( key ) :
self . press_mem [ key ] = True
clicked [ key ] = True
print ( clicked )
for key in self . press_mem :
if not state_dict . get ( key ) :
self . press_mem [ key ] = False
if state_dict . get ( " paused " ) == 1 :
if self . pause_mode [ ' active ' ] is True :
output = list ( )
2024-08-06 12:41:40 -04:00
print ( ( self . pause_mode ) )
2024-08-05 13:41:50 -04:00
if self . pause_mode [ ' active ' ] is False and clicked . get ( ' start ' ) :
self . pause_mode [ ' active ' ] = True
self . pause_mode [ ' goal ' ] = " menu "
self . pause_mode [ ' select ' ] = 0
output = [ " AI Menu " ]
if typ == " map " :
self . pause_mode [ ' menu ' ] = [ str ( i + 1 ) + " : " + " " . join ( x . strip ( ) . split ( " " ) [ : - 2 ] ) + " , " for i , x in enumerate ( specials_list ) ]
self . pause_mode [ ' total ' ] = len ( self . pause_mode [ ' menu ' ] )
#output.extend(self.pause_mode['menu'])
elif clicked . get ( " start " ) and self . pause_mode [ ' goal ' ] == " menu " :
#activate menu selection
output = [ " Going to: " + self . pause_mode [ ' menu ' ] [ self . pause_mode [ ' select ' ] ] . partition ( " : " ) [ 2 ] ]
self . pause_mode [ ' goal ' ] = self . pause_mode [ ' menu ' ] [ self . pause_mode [ ' select ' ] ]
elif self . pause_mode [ ' active ' ] and state_dict . get ( " start " ) and self . pause_mode [ ' goal ' ] != " menu " :
pass
elif self . pause_mode [ ' active ' ] and not state_dict . get ( " start " ) and self . pause_mode [ ' goal ' ] != " menu " :
2024-08-06 12:41:40 -04:00
print ( ( self . pause_mode [ ' goal ' ] ) )
2024-08-05 13:41:50 -04:00
press_output = [ " unpause " ]
elif self . pause_mode [ ' active ' ] and self . pause_mode [ ' total ' ] > 0 :
if state_dict . get ( " a " ) : #clicked.get("a"):
self . pause_mode [ ' select ' ] + = 1
if state_dict . get ( " b " ) : #clicked.get("b"):
self . pause_mode [ ' select ' ] - = 1
if self . pause_mode [ ' select ' ] < 0 :
self . pause_mode [ ' select ' ] + = self . pause_mode [ ' total ' ]
if self . pause_mode [ ' select ' ] > = self . pause_mode [ ' total ' ] :
self . pause_mode [ ' select ' ] - = self . pause_mode [ ' total ' ]
if self . pause_mode [ ' active ' ] and self . pause_mode [ ' goal ' ] == " menu " :
if self . pause_mode [ ' total ' ] > 0 :
output . append ( " Go to: " + self . pause_mode [ ' menu ' ] [ self . pause_mode [ ' select ' ] ] )
else :
if self . pause_mode [ ' active ' ] and self . pause_mode [ ' goal ' ] != " menu " :
#move to target
#find shortest path to target here...
#aaa AAA
goal = self . pause_mode [ ' goal ' ]
num = int ( goal . partition ( " : " ) [ 0 ] ) - 1
target = goal . partition ( " : " ) [ 2 ]
count = 0
x , y = None , None
special_flag = False
print ( k )
for entry in k :
ee = target . partition ( " , " ) [ 0 ]
if " special " in entry :
special_flag = True
if ee in entry and special_flag :
count + = 1
coords = entry . partition ( ee ) [ 2 ] . strip ( ) . split ( " " )
x , y = int ( coords [ 0 ] ) , int ( coords [ 1 ] )
if count == num :
break
if path_data and x is not None and y is not None :
path = PathFinder . find_path ( path_data , 6 - y , 7 + x )
2024-08-06 12:41:40 -04:00
print ( ( " X Y " , x , y , target , num , goal ) )
2024-08-05 13:41:50 -04:00
if path :
vy = - 1 * path [ 0 ] [ 2 ]
vx = path [ 0 ] [ 3 ]
if vx != None :
if vy < 0 :
press_output . append ( " down " )
elif vy > 0 :
press_output . append ( " up " )
elif vx < 0 :
press_output . append ( " left " )
elif vx > 0 :
press_output . append ( " right " )
2024-08-06 12:41:40 -04:00
print ( ( " AAAA " , map_data [ ' tiles ' ] [ 6 - vy ] [ 7 + vx ] [ ' type ' ] , target ) )
2024-08-05 13:41:50 -04:00
if map_data [ ' tiles ' ] [ 6 - vy ] [ 7 + vx ] [ ' type ' ] == target . replace ( " , " , " " ) . strip ( ) :
press_output . append ( " a " )
output = list ( )
if " unknown " not in " " . join ( k ) . partition ( " special " ) [ 0 ] and ( count == 0 or abs ( x ) + abs ( y ) < = 1 ) :
self . pause_mode [ ' active ' ] = False
self . pause_mode [ ' goal ' ] = ' menu '
else :
output = list ( )
else :
self . pause_mode [ ' active ' ] = False
self . pause_mode [ ' goal ' ] = ' menu '
output = [ ' No path available ' ]
else :
output = list ( )
elif self . pause_mode [ ' active ' ] :
if self . pause_mode [ ' goal ' ] == " menu " :
self . pause_mode [ ' active ' ] = False
else :
pass
if typ != " map " :
self . pause_mode [ ' active ' ] = False
self . pause_mode [ ' goal ' ] = ' menu '
return output , press_output
def run ( self , im , state_dict ) :
new_out = self . get_output ( im , state_dict )
return new_out
def main_b ( ) :
doc = json . loads ( open ( " ff1_data.lud " , " r " ) . read ( ) )
tile_info = doc [ ' tile_info ' ]
lud = doc [ ' lud ' ]
plud = doc [ ' plud ' ]
for i in range ( 10 ) :
im = Image . open ( " maps_ " + str ( 2 + i ) + " .png " )
t = time . time ( )
k , map_data = ParseScreenObstructions . parse_screen ( im , tile_info , lud ,
plud , partial_center = True )
2024-08-06 12:41:40 -04:00
print ( ( time . time ( ) - t ) )
2024-08-05 13:41:50 -04:00
import pdb
pdb . set_trace ( )
def main_c ( ) :
po = PackageOutput ( " ff1_data.lud " , " enemy_lookup.dat " )
for i in range ( 10 ) :
im = Image . open ( " maps_ " + str ( 2 + i ) + " .png " )
t = time . time ( )
2024-08-06 12:41:40 -04:00
print ( ( " -- " , po . memory ) )
print ( ( po . run ( im ) ) )
print ( ( time . time ( ) - t ) )
2024-08-05 13:41:50 -04:00
import pdb
pdb . set_trace ( )
class ParseScreenObstructions :
@classmethod
def parse_screen ( cls , im , tile_info , lud , plud , partial_center = False ) :
off_x = tile_info [ ' off_x ' ] #0
off_y = tile_info [ ' off_y ' ] #8
tilesize = tile_info [ ' tilesize ' ]
map_data = { " center " : [ 6 , 7 ] , " tiles " : [ ] }
#AAAAAAAAaaaaaaaaaaa
#-start at center of the screen, go out in 4 directions and
# get the tiles
screen = TileTools . parse_tiles ( im , off_x , off_y , tilesize ,
partial_center = partial_center )
horizontal = list ( )
vertical = list ( )
special = list ( )
unknown_limit = 32
unknown_count = 0
for y , row in enumerate ( screen ) :
map_data [ ' tiles ' ] . append ( [ ] )
for x , tile in enumerate ( row ) :
person = None
if partial_center == True and x == 7 and y == 5 :
doc = None
for key in lud :
#bmps are stored upside down, so do endswith here..
2024-08-06 13:14:12 -04:00
if key . endswith ( tile [ int ( - len ( tile ) * 3 / 4 ) : ] ) :
2024-08-05 13:41:50 -04:00
doc = lud . get ( key )
break
else :
doc = lud . get ( tile )
if doc is None and tile is not None :
#check person tiles
pt = load_image ( tile )
cropped = pt . crop ( plud [ ' person_box ' ] )
pkey = image_to_string_format ( cropped , " BMP " )
if pkey in plud [ ' person_dict ' ] :
person = plud [ ' person_dict ' ] [ pkey ]
doc = { " obs " : person [ ' obs ' ] ,
" type " : person [ ' type ' ] ,
" num " : person [ ' num ' ] ,
" raw_i " : person [ ' raw_i ' ] }
else :
#handle tiles that are overlayed a bit with a
#sprite below them
for key in lud :
#bmps are stored upside down, so do endswith here..
2024-08-06 14:03:13 -04:00
if key . endswith ( tile [ int ( - len ( tile ) * 3 / 4 ) : ] ) :
2024-08-05 13:41:50 -04:00
doc = lud . get ( key )
break
else :
unknown_count + = 1
if y == 6 :
horizontal . append ( doc )
if x == 7 :
vertical . append ( doc )
map_data [ ' tiles ' ] [ - 1 ] . append ( doc )
if doc and ( doc [ ' obs ' ] in [ 2 , 3 ] or person ) :
if doc [ ' type ' ] != ' bat ' :
special . append ( [ x , y , doc , tile ] )
if unknown_count > unknown_limit :
horizontal = [ None for x in horizontal ]
vertical = [ None for x in vertical ]
special_groups = dict ( )
for tup in sorted ( special , key = lambda x : ( x [ 0 ] , x [ 1 ] ) ) :
if tup [ 2 ] [ ' type ' ] not in special_groups :
special_groups [ tup [ 2 ] [ ' type ' ] ] = [ [ tup ] ]
else :
for entry_tup in special_groups [ tup [ 2 ] [ ' type ' ] ] :
for e_tup2 in entry_tup :
if abs ( tup [ 0 ] - e_tup2 [ 0 ] ) + abs ( tup [ 1 ] - e_tup2 [ 1 ] ) < 2 :
entry_tup . append ( tup )
break
else :
continue
break
else :
special_groups [ tup [ 2 ] [ ' type ' ] ] . append ( [ tup ] )
new_special = list ( )
for ent_group in special_groups :
for ent in special_groups [ ent_group ] :
num = 0
sx = 0
sy = 0
for tup in ent :
sx + = tup [ 0 ]
sy + = tup [ 1 ]
num + = 1
ent [ 0 ] [ 0 ] = int ( sx / num )
ent [ 0 ] [ 1 ] = int ( sy / num )
new_special . append ( ent [ 0 ] )
special = new_special
results = { " horizontal " : horizontal , " vertical " : vertical ,
" special " : special , " im " : im }
return cls . output_to_text ( results ) , map_data
#-compute the tile types (obstruction or not, special or not).
#--have sound types for wood, brick, water, etc.
#-convert to sound info.
#--if no info found, assume that the play moved a bit.
pass
@classmethod
def output_to_text ( cls , results ) :
west_obs = None
east_obs = None
south_obs = None
north_obs = None
for i , doc in enumerate ( results [ ' horizontal ' ] ) :
if doc and i != 7 and doc [ ' obs ' ] % 2 == 1 :
if i < 7 :
west_obs = 6 - i ;
if i > 7 and east_obs == None :
east_obs = i - 8 ;
for j , doc in enumerate ( results [ ' vertical ' ] ) :
2024-08-06 12:41:40 -04:00
if doc and j != 6 and doc [ ' obs ' ] % 2 == 1 :
2024-08-05 13:41:50 -04:00
if j < 6 :
north_obs = 5 - j ;
if j > 6 and south_obs == None :
south_obs = j - 7 ;
west_tile = results [ ' horizontal ' ] [ 6 ]
if west_tile is not None :
west_tile = west_tile [ ' type ' ]
else :
west_tile = " unknown "
east_tile = results [ ' horizontal ' ] [ 8 ]
if east_tile is not None :
east_tile = east_tile [ ' type ' ]
else :
east_tile = " unknown "
south_tile = results [ ' vertical ' ] [ 7 ]
if south_tile is not None :
south_tile = south_tile [ ' type ' ]
else :
south_tile = " unknown "
north_tile = results [ ' vertical ' ] [ 5 ]
if north_tile is not None :
north_tile = north_tile [ ' type ' ]
else :
north_tile = " unknown "
outputs = [ " west " + str ( west_obs ) + " " + west_tile ,
" north " + str ( north_obs ) + " " + north_tile ,
" east " + str ( east_obs ) + " " + east_tile ,
" south " + str ( south_obs ) + " " + south_tile ]
sp = dict ( )
sp_a = list ( )
for k , doc in enumerate ( results [ ' special ' ] ) :
x , y = doc [ 0 ] - 7 , doc [ 1 ] - 6
angle = math . atan2 ( - y , x )
while angle < 0 :
angle + = math . pi * 2
while angle > math . pi * 2 :
angle - = math . pi * 2
if math . pi / 8 < = angle < = 3 * math . pi / 8 :
dr = " northeast "
elif 3 * math . pi / 8 < angle < = 5 * math . pi / 8 :
dr = " north "
elif 5 * math . pi / 8 < angle < = 7 * math . pi / 8 :
dr = " northwest "
elif 7 * math . pi / 8 < angle < = 9 * math . pi / 8 :
dr = " west "
elif 9 * math . pi / 8 < angle < = 11 * math . pi / 8 :
dr = " southwest "
elif 11 * math . pi / 8 < angle < = 13 * math . pi / 8 :
dr = " south "
elif 13 * math . pi / 8 < angle < = 15 * math . pi / 8 :
dr = " southeast "
elif angle < math . pi / 8 or angle > 15 * ( math . pi / 8 ) :
dr = " east "
"""
if math . pi / 4 < = angle < = 3 * math . pi / 4 :
dr = " north "
elif 3 * math . pi / 4 < angle < = 5 * math . pi / 4 :
dr = " west "
elif 5 * math . pi / 4 < angle < = 7 * math . pi / 4 :
dr = " south "
elif angle < math . pi / 4 or angle > 7 * ( math . pi / 4 ) :
dr = " east "
"""
sp_a . append ( doc [ 2 ] [ ' type ' ] + " " + str ( x ) + " " + str ( - 1 * y ) + " " )
if dr not in sp :
sp [ dr ] = OrderedDict ( )
sp [ dr ] [ doc [ 2 ] [ ' type ' ] ] = 1
if sp :
outputs . append ( " special " )
outputs . extend ( sp_a )
"""
for key in [ ' west ' , ' northwest ' , ' north ' , ' northeast ' ,
' east ' , ' southeast ' , ' south ' , ' southwest ' ] :
if sp . get ( key ) :
outputs . append ( key )
for subkey in sp [ key ] :
outputs [ - 1 ] = outputs [ - 1 ] + " " + subkey
"""
return outputs
class ParseScreenText :
@classmethod
def get_font ( cls , text_image_list ) :
found_tiles = OrderedDict ( )
for image in text_image_list :
for j in range ( int ( image . height / 8 ) ) :
for i in range ( int ( image . width / 8 ) ) :
subi = image . crop ( ( i * 8 , j * 8 , i * 8 + 8 , j * 8 + 8 ) )
ss = image_to_string_format ( subi , " BMP " )
found_tiles [ ss ] = found_tiles . get ( ss , 0 ) + 1
seen = OrderedDict ( )
c = 0
for i , ch in enumerate ( found_tiles ) :
ss = image_to_string_format ( reduce_to_colors ( load_image ( ch ) . convert ( " P " , palette = Image . ADAPTIVE ) , [ " FFFFFF " ] , 32 ) , " BMP " )
if ss not in seen :
c + = 1
seen [ ss ] = ch
im = Image . new ( " RGB " , ( 8 * c , 8 ) )
for c , k in enumerate ( seen ) :
ch = seen [ k ]
im . paste ( load_image ( ch ) , ( c * 8 , 0 ) )
2024-08-06 12:41:40 -04:00
kk = list ( found_tiles . keys ( ) )
2024-08-05 13:41:50 -04:00
stra = [ x for x in " >>ABCDEFGHIJ KLMNOPQRSTUVWXYZ ' ,.123456789abcdefghijklmnopqrstuvwxyz- " ]
stra . extend ( [ " .. " , " ! " , " ? " , " " , " " , " " , " " , " " , " " , " " , " " , " > " , " > " , " " , " " , " Mail " , " Rod " , " " , " Sword " , " " , " " , " " , " " , " " , " " , " " , " Nunchucks " , " " , " " , " Hammer " , " " , " " , " " , " Level " , " / " , " Weapon " , " " , " " , " " , " " , " Status " , " " , " " , " " , " " , " " , " " , " > " , " > " , " " , " E " , " > " , " > " , " Fight " , " " , " " , " " , " " , " " , " Magic " , " " , " " , " " , " Drink " , " " , " " , " " ] )
output_dict = OrderedDict ( )
2024-08-06 12:41:40 -04:00
kk2 = [ seen [ x ] for x in list ( seen . keys ( ) ) ]
2024-08-05 13:41:50 -04:00
for i , ch in enumerate ( kk2 ) :
subi = load_image ( ch )
new_subi = reduce_to_colors ( subi . convert ( " P " , palette = Image . ADAPTIVE ) , [ " FFFFFF " ] , 32 )
str_image = image_to_string_format ( new_subi , " BMP " )
if i < len ( stra ) and str_image not in output_dict :
output_dict [ str_image ] = stra [ i ]
return output_dict
@classmethod
def parse_screen ( cls , im , font_dict ) :
im = reduce_to_colors ( im . convert ( " P " , palette = Image . ADAPTIVE ) , [ " FFFFFF " ] , 32 ) . convert ( " RGB " )
text = [ [ ] ]
for j in range ( int ( im . height / 8 ) ) :
for i in range ( int ( im . width / 8 ) ) :
subi = im . crop ( ( i * 8 , j * 8 , i * 8 + 8 , j * 8 + 8 ) )
subi_key = image_to_string_format ( subi , " BMP " )
value = font_dict . get ( subi_key , " " )
text [ - 1 ] . append ( value )
text . append ( [ ] )
output = list ( )
current_output = " "
si = 0
sj = 0
for j , line in enumerate ( text ) :
for i , ch in enumerate ( line ) :
if ch . strip ( ) or current_output :
if not current_output :
current_output = ch
si = i
sj = j
elif ch == " > " and current_output [ - 1 ] != " > " :
output . append ( [ ( si , sj ) , current_output ] )
current_output = " > "
si = i
sj = j
elif ch == " " and current_output [ - 1 ] == " " and current_output [ - 2 ] == " " :
output . append ( [ ( si , sj ) , current_output ] )
current_output = " "
else :
current_output + = ch
if current_output :
output . append ( [ ( si , sj ) , current_output . replace ( " _ " , " .. " ) ] )
current_output = " "
return output
class TileTools :
@classmethod
def parse_tiles ( cls , im , off_x , off_y , tilesize , partial_center = False ) :
cx = off_x
cy = off_y
res = OrderedDict ( )
rr = [ [ ] ]
while True :
if cx + tilesize < im . size [ 0 ] :
sim = im . crop ( ( cx , cy , cx + tilesize , cy + tilesize ) )
s = image_to_string_format ( sim , format_type = " BMP " )
if cy in [ 88 , 104 ] and cx == 112 :
#if cy == 104 or partial_center == False:
if partial_center == False :
s = None
rr [ - 1 ] . append ( s )
cx + = tilesize
elif cy + tilesize < im . size [ 1 ] - tilesize :
cx = off_x
cy + = tilesize
rr . append ( [ ] )
else :
break
return rr
@classmethod
def get_tiles ( cls , im , off_x , off_y , tilesize ) :
rr = cls . parse_tiles ( im , off_x , off_y , tilesize )
res = OrderedDict ( )
for y , row in enumerate ( rr ) :
for x , tile in enumerate ( row ) :
if tile :
res [ tile ] = res . get ( tile , 0 ) + 1
return res
@classmethod
def find_tileset_offset ( cls , im , tilesize ) :
ress = list ( )
for x in range ( tilesize ) :
for y in range ( tilesize ) :
tiles = cls . get_tiles ( im , x , y , tilesize )
ress . append ( [ x , y , len ( tiles ) , tiles ] )
ress . sort ( key = lambda x : x [ 2 ] )
return ress [ 0 ] [ 0 : 2 ]
def to_image_key ( img ) :
2024-08-06 12:41:40 -04:00
if isinstance ( img , str ) :
2024-08-05 13:41:50 -04:00
img = load_image ( img )
key = image_to_string_format ( img , " BMP " )
return key
class ScreenSelector :
shop_image = load_image ( " iVBORw0KGgoAAAANSUhEUgAAAKAAAAAYCAIAAADyNGFiAAAAhUlEQVR4nO3UMQ6AIAxGYTTqGekJ6Rl1cSAQNnCqbd43Mf7hBVICAAAAAAAAAHOb9QA3cs7WEz5Q1Xog8JJat5RiPWSJiKTWmMBzY916d3827lTV3XqPD17qpjayfzaH6RhP6sWdelsPmXjyJSI9MC84OAIHR+DgCBwcgYMjcHAEDo7Awb3rRh8l+sp+JAAAAABJRU5ErkJggg== " )
battle_image = to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAQAAAAAICAIAAACZNLboAAAAgklEQVR4nO3UMRKAIAwEQHR8ZPJCeKZFGiQClUxObkuhOG4SUyIiIiLazjG9ISILcpAppTRfsPr3+YObLIC1n3NeEmZ3qpqeM4TVv88f32gB6vbtbfSdumebIaz+fX4I5/gYpf0fsJKbnz1Q/6/547umN+B2GpSIqKofIJT+e/mDuwF7dj4gb9hPPAAAAABJRU5ErkJggg== " )
char_select = to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAQAAAAAgCAIAAAByyzGzAAAAjklEQVR4nO3W0QlCMRAEwCiWpL3kKkx60aL8CMorIK7wmGlguT0upDUAAAAAAAAAAAAAAAAAAAAAAAAAgL+5xJJ677GsvDlnOFGfW4QOYG1rjJGJC6uqlr0Bfe6SOIDjttZsZ3KcK7MzfW50/XXActZttc9Q4cdYn7vcMjHte9PPeywxoz9eVZX/jehzizf4UD4gJtsg3gAAAABJRU5ErkJggg== " )
empty_orb = to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAdUlEQVR4nJVSwRGAMAijPTdxBd1FdnKPuIsO5cM7jIjU5lcuITnSIuMqPRjeo2U++Lnt06fAqADuqSrLikVyi1mppKl54ovKhjVZzxrjNBxctg6BIThrkuqvAwAfybXj2MxpR6I8zx4SEwmbNuR/KRDk6O7hBC14K/+LWlBvAAAAAElFTkSuQmCC " )
item_sub_menu = to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAQAAAABcCAIAAAAOK/wJAAAAuklEQVR4nO3WsQ0CMQwF0IAYCXaJJ0x2gaEorrkqvuKIdOS92rJc/K+kFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABggls6UWudcAf8Qu99PJAUYEt/a+20i2CWiChZB0YF2Kd/2wVXsc/toAP341vgQrbQpp+Xx8FF/f085SyYo74+EZEWIHkB4L8pAEtTAJamACztC+hvHx3TeOZ7AAAAAElFTkSuQmCC " )
formation_menu = to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAQAAAAAwCAIAAABxHTMoAAAAqElEQVR4nO3VwQ0CIRRFUTSWpL1AhdCLFuUCF7OcmEl+4J9TwQvDHUoBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALjcLXpAmFpr9ISFjTGiJ1wjaQDz9vfeo4csqbVWdmkgYwDH2z+/Jecdz22DBu7RA2K4/X+bh7bN4/mIHhDm9w97P6OHLKa+Pq21bQJI+gLAJABSEwCpCYDUBEBqAiA1AZCaAEjtC0NpHyXvFRJOAAAAAElFTkSuQmCC " )
empty_battle_char = to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAABAAAAAYCAIAAAB8wupbAAAAEklEQVR4nGNgGAWjYBSMgsEFAASYAAHgYt7ZAAAAAElFTkSuQmCC " )
empty_battle_char = to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAAgAAAAYCAIAAABIuytHAAAAD0lEQVR4nGNgGAWjgPoAAAJYAAGgxYwDAAAAAElFTkSuQmCC " )
battle_enemies_dict = dict ( )
font_dict = dict ( )
luds = dict ( )
@classmethod
def _load_content ( cls , fonts , tilesets , spritesets , filename_lud , enemy_filename ) :
if enemy_filename :
cls . battle_enemies_dict = json . loads ( open ( enemy_filename ) . read ( ) )
else :
for filename in os . listdir ( " ./ " ) :
if filename . startswith ( " enemy_ " ) and filename . count ( " _ " ) > 1 :
n = filename . partition ( " enemy_ " ) [ 2 ] . partition ( " .png " ) [ 0 ] . partition ( " _ " ) [ 0 ]
key = to_image_key ( Image . open ( filename ) )
cls . battle_enemies_dict [ key ] = cls . _parse_enemy_name ( n )
ff = open ( " ./enemy_lookup.dat " , " w " )
ff . write ( json . dumps ( cls . battle_enemies_dict ) )
ff . close ( )
cls . luds = json . loads ( open ( filename_lud ) . read ( ) )
#images have different bmp headers sometimes, so reformat them here.
new_dict = dict ( )
2024-08-06 12:41:40 -04:00
for key , val in list ( cls . luds [ ' plud ' ] [ ' person_dict ' ] . items ( ) ) :
2024-08-05 13:41:50 -04:00
new_dict [ image_to_string_format ( load_image ( key ) , " BMP " ) ] = val
cls . luds [ ' plud ' ] [ ' person_dict ' ] = new_dict
new_dict = dict ( )
2024-08-06 12:41:40 -04:00
for key , val in list ( cls . luds [ ' lud ' ] . items ( ) ) :
2024-08-05 13:41:50 -04:00
new_dict [ image_to_string_format ( load_image ( key ) , " BMP " ) ] = val
cls . luds [ ' lud ' ] = new_dict
image_list = [ Image . open ( " text " + str ( i ) + " .png " ) for i in range ( 7 ) ]
cls . font_dict = ParseScreenText . get_font ( image_list )
cls . _load_worldmap ( )
@classmethod
def _parse_enemy_name ( cls , n ) :
n = n . lower ( )
if n == " blue d " :
return " blue dragon "
elif n == " frost d " :
return " frost dragon "
elif n [ : 2 ] == " fr " and len ( n ) > 4 :
return " frost " + n [ 2 : ]
elif n == " gas d " :
return " gas dragon "
elif n == " grey w " :
return " grey worm "
elif n [ : 2 ] == " gr " and len ( n ) > 4 :
return " greater " + n [ 2 : ]
elif n == " irongol " :
return " iron golem "
elif n == " manticor " :
return " manticore "
elif n == " mudgol " :
return " mud golem "
elif n == " r.goyle " :
return " red gargoyle "
elif n == " red d " :
return " red dragon "
elif n [ : 2 ] == " r. " and len ( n ) > 4 :
return " red " + n [ 2 : ]
elif n == " rockgol " :
return " rock golem "
elif n == " saber t " :
return " saber tooth "
elif n == " sand w " :
return " sand worm "
elif n == " tyro " :
return " t rex "
elif n == " wzvamp " :
return " vampire wizard "
elif n [ : 2 ] == " wz " and len ( n ) > 4 :
return n [ 2 : ] + " wizard "
elif n == " zombied " :
return " zombie dragon "
elif n == " zombull " :
return " zombie bull "
else :
return n
@classmethod
def parse_whole_screen ( cls , image ) :
#image_list = [Image.open("text"+str(i)+".png") for i in range(7)]
#f = ParseScreenText.get_font(image_list)
map_data = dict ( )
text = ParseScreenText . parse_screen ( image , cls . font_dict )
if text :
if cls . is_shop ( image ) :
return ' shop ' , cls . shop_parse ( image , text ) , map_data
elif cls . is_battle ( image ) :
return ' battle ' , cls . battle_parse ( image , text ) , map_data
elif cls . is_menu ( image , text ) :
return ' menu ' , cls . menu_parse ( image , text ) , map_data
else :
return ' text ' , cls . text_box ( image , text ) , map_data
else :
if cls . is_world_map ( image ) :
return ' world ' , cls . world_map_parse ( image ) , map_data
else :
k , map_data = ParseScreenObstructions . parse_screen ( image ,
cls . luds [ ' tile_info ' ] ,
cls . luds [ ' lud ' ] ,
cls . luds [ ' plud ' ] ,
partial_center = True )
return ' map ' , k , map_data
world_map_title = to_image_key ( ' iVBORw0KGgoAAAANSUhEUgAAAIAAAAAgCAIAAABVQOdyAAAD80lEQVR4nO1avXHzMAxFfGlTaRAtoMqdh/B5sK/SaQh3rryABnHl3vcVjJFn/JGiLKbJuxQ5EgRIgCLAR39Q94+2x/F2jgWm7mCKpXatB9vFKLNL6MnOypTfAp8NbKR1jvOAjaf++tLYn9Oax3k49VduH+m+238Zep7y3MgKp71hlxvjWf3gqX9r7LY24Hl/nAds1I5IDvX0jPPA+zc1JoU8KuNfyyhajAe+EZsHgJ7bE/+ClWf1EHw9ycs8/NRfcdvqeAjglHRX4epWokUACI5UdD17c+oOJQsOZFKXODRejjK1o6fuYB4yKR7NckCLAOz2X8GBkJaaXbB2rqeQIXr1R2DOygvMRtg8AObeZ5z66+NyF42BW3VXOvo95fiPGY9mZ72HRkeQiazjYqB/9ZAUeDOT4wTKZ7sRfjMApuPeC+HibK3VHu0CYC51nAcu88uViGPH3Mi42VEA23/d+9S4Clq5YE4nQfmISH4XkhyMxsnWQ7ubcMKaGHi1vMgl2tzUHY63M1elScAsq4jocbnjJLcO0sfWXJAoNtgLvEhB3eg7mqAcRC82evWu2R4XxyhWvNYaNLoJi/+TW8UhEHhf68Fe8VWZQRKS+kTSaFAjUJsjyKsRs5LeKaF7v7useJhKMJ14026TITY/gv4QY9UXUMjyC2FvZ5Vz/d4DgGei3LQ3eXJSd1ZzFvUB0Ec2vfJfRAZrTxY1LwRirt/InL2836KJZaYRvfT4OA/4TmDOeSkqj6Ai7xORVWzoukK7ICVYYcVs1MDUnTXtrQXnL8S8Z4O6eqmmCkpTERR/zPJnqfmlXD+pG5YnljUttPE0dvsv4VOsesX7T3W9VF+GYhHpsfy8gJiap3ABom7hxwN+wiQoGfU5kDXtdR1v5zjJveW+tuoekE3CjJiaX8r16wecYP2xaUEZ8aWa/8cwaGqPWx6Xu+bVS1CZhHlre9tZZEL2KTMHOh+aXL9WblYjAbKmMcnr4Yku9HIewSdI9H0RWYSaLyBevGb5Kz7PmOvHF/kYhb9G0XNe+lBcTe29n4rwbvBihXUfrKdtkXDJTwLilwM8psqnYWJtAEpY/hJqnuCLznL95nBuxPZFpk14uf1dWBWA8mnF1Dy9kjMlXD8Oj8m47KuAKWOStdrWerZu1U2YXqtsTyYhoOY9aK4f21EtFiqn/krdYZFp062sitv59hPMeSkqA4A3zBF+TPizfdSV1SQDcBRrS10l6zRjMz29L86xrGlTlbZoJ+f294BClh8RUPOFXL8ebo4yFRaa1qoEOEvx17kmQ9RzQbrRYwq1AHZNr8cFSgqx2Lqnf6lpcy2kaKWE9Sn67z1gAbK/nq/Afw+oxUTPNFf0AAAAAElFTkSuQmCC ' )
@classmethod
def is_world_map ( cls , image ) :
if to_image_key ( image . crop ( ( 64 , 16 , 192 , 48 ) ) ) == cls . world_map_title :
return True
return False
@classmethod
def _load_worldmap ( cls ) :
cls . world_mask = load_image ( " iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAIAAABMXPacAAAAxklEQVR4nO3cMQ6DMAwFUNT739kduiCVoQ0h/IT3dkSIDRgD2TYAAAAAgOlU1b+bvBIGsYbHHjgAAAxXVQpwZnOYsxI5gjAAXahPftG/Hd3sO1oh8QsZBsDTuRwDAAAAAABxfJkAAACw5xEJOEmzBQAAAADW16UJGLRayly0YLmS/GJ1I3Pc+XRg2KvEz17E4DamHgA4L3ZxWwC4ilsdrZpzR9KRR1YCACxPyQcAQDqr5tzM7M+ag/4RAwCAnRmLegAAAPK9Aa6QfYsCj718AAAAAElFTkSuQmCC " ) . convert ( " RGB " )
cls . locals = list ( )
for i in range ( cls . world_mask . width ) :
for j in range ( cls . world_mask . height ) :
if cls . world_mask . getpixel ( ( i , j ) ) == ( 255 , 255 , 255 ) :
cls . locals . append ( ( i , j ) )
new_output = list ( )
for x1 , y1 in cls . locals :
for tup in new_output :
for x , y in tup :
if abs ( x1 - x ) + abs ( y - y1 ) < 3 :
tup . append ( ( x1 , y1 ) )
break
else :
continue
break
else :
new_output . append ( [ ( x1 , y1 ) ] )
new_output2 = list ( )
for tup in new_output :
cx = 0
cy = 0
cc = 0
for x , y in tup :
cx + = x
cy + = y
cc + = 1
cx = int ( cx / float ( cc ) )
cy = int ( cy / float ( cc ) )
new_output2 . append ( [ cx , cy , cc ] )
landmark_types = [ " Gaint ' s cave " , " Sage ' s cave " , " Gaint ' s cave " , " Waterfall " , " Onrac " , " Earth cave " , " Cardia " , " Melmond " , " Cardia " , " Cardia " , " Cardia " , " Dwarf cave " , " Northwest castle " , " Marsh cave " , " Cardia " , " Cardia " , " Castle of Ordeal " , " Temple of Fiends " , " Elfhland " , " Corneria " , " Matoya ' s cave " , " Guru volcano " , " Mirage Tower " , " Ice cave " , " Pravoka " , " Crescent lake " , " Gaia " , " Lefein "
]
for i , tup in enumerate ( new_output2 ) :
tup . append ( landmark_types [ i ] )
tup . extend ( [ [ 110 , 118 , " Desert " ] , [ 108 , 25 , " Landing spot " ] , [ 20 , 39 , " Landing spot " ] , [ 60 , 18 , " Landing spot " ] ] )
cls . world_landmarks = new_output2
@classmethod
def world_map_parse ( cls , image ) :
cropped = image . crop ( ( 64 , 48 , 192 , 176 ) ) . convert ( " P " , palette = Image . ADAPTIVE )
p = cropped . getpalette ( )
new_palette = list ( )
default_color = ( 0 , 0 , 0 )
threshold = 32
for i in range ( 256 ) :
r = p [ 3 * i ]
g = p [ 3 * i + 1 ]
b = p [ 3 * i + 2 ]
for cc in [ ( 0 , 19 , 155 ) , ( 0 , 120 , 82 ) ,
( 17 , 209 , 164 ) , ( 233 , 211 , 134 ) ] :
val = ( cc [ 0 ] - r ) * * 2 + ( cc [ 1 ] - g ) * * 2 + ( cc [ 2 ] - b ) * * 2
if val < = threshold * * 2 :
new_palette . extend ( default_color )
break
else :
new_palette . extend ( ( 255 , 255 , 255 ) )
cropped . putpalette ( new_palette )
cropped = cropped . convert ( " RGB " )
outputi = ImageChops . difference ( cropped . convert ( " RGB " ) , cls . world_mask . convert ( " RGB " ) )
for c in outputi . convert ( " RGB " ) . getcolors ( ) :
if c [ 1 ] == ( 255 , 255 , 255 ) :
if c [ 0 ] > 0 :
break
else :
return [ ]
cx = 0
cy = 0
n = 0
for i in range ( outputi . width ) :
for j in range ( outputi . height ) :
if outputi . getpixel ( ( i , j ) ) == ( 255 , 255 , 255 ) :
cx + = i
cy + = j
n + = 1
cx = int ( cx / float ( n ) )
cy = int ( cy / float ( n ) )
output = list ( )
output . append ( " location: " + str ( cx * 2 ) + " , " + str ( ( outputi . height - cy ) * 2 ) + " , " )
for entry in cls . world_landmarks :
if abs ( entry [ 0 ] - cx ) + abs ( entry [ 1 ] - cy ) < 32 :
zx = entry [ 0 ] - cx
zy = cy - entry [ 1 ]
zc = entry [ 2 ]
z_name = entry [ 3 ]
#if zc > 1:
# typ = "major"
#else:
# typ = "minor"
typ = z_name
string = typ + " , " + str ( zx * 2 ) + " , " + str ( zy * 2 ) + " , "
output . append ( string )
print ( output )
return output
@classmethod
def is_battle ( cls , image ) :
#check for battle backgrounds
color1 = image . getpixel ( ( 0 , 0 ) )
crop = image . crop ( ( 0 , 0 , 256 , 8 ) )
crop = replace_color ( crop , color1 , ( 0 , 0 , 0 ) )
key = to_image_key ( crop )
if key == cls . battle_image :
return True
return False
@classmethod
def battle_parse ( cls , image , text ) :
textbox = list ( )
player_names = [ " " for x in range ( 4 ) ]
player_hps = [ " " for x in range ( 4 ) ]
for tup , string in text :
x , y = tup
if x > = 26 and y < 26 :
textbox . append ( string )
if y == 4 :
player_names [ 0 ] = string . strip ( )
elif y == 7 :
player_hps [ 0 ] = string . strip ( )
elif y == 10 :
player_names [ 1 ] = string . strip ( )
elif y == 13 :
player_hps [ 1 ] = string . strip ( )
elif y == 16 :
player_names [ 2 ] = string . strip ( )
elif y == 19 :
player_hps [ 2 ] = string . strip ( )
elif y == 22 :
player_names [ 3 ] = string . strip ( )
elif y == 25 :
player_hps [ 3 ] = string . strip ( )
textbox = " " . join ( textbox )
enemy_names = list ( )
for tup , string in text :
x , y = tup
if x == 3 and y > = 19 :
enemy_names . append ( string . strip ( ) )
enemies = list ( )
coords = [ ( 16 , 40 , 32 , 32 ) ]
enemy_count = OrderedDict ( )
boxes_to_check = list ( )
for i in range ( 3 ) :
for j in range ( 3 ) :
x = 16 + 32 * i
y = 40 + 32 * j
w = 32
h = 32
boxes_to_check . append ( ( ( x , y , w , h ) , ( i , j ) , i * 3 + j + 1 ) )
#check for big enemy plus 3 small
for i in range ( 3 ) :
for j in range ( 3 ) :
x = 32 + 32 * i
y = 40 + 32 * j
w = 32
h = 32
boxes_to_check . append ( ( ( x , y , w , h ) , ( i , j ) , j + 1 ) )
#check for garland box
#boxes_to_check.append(((64, 72, 32, 32), (1,1), 1))
#check for big enemies v1
for i in range ( 2 ) :
for j in range ( 2 ) :
x = 16 + 64 * i
y = 40 + 48 * j
w = 48
h = 48
boxes_to_check . append ( ( ( x , y , w , h ) , ( i * 2 , j ) , i * 2 + j + 1 ) )
#check for big enemies v2
for i in range ( 1 ) :
for j in range ( 2 ) :
x = 16 + 48 * 1
y = 40 + 48 * j
w = 48
h = 48
boxes_to_check . append ( ( ( x , y , w , h ) , ( i , j ) , i * 2 + j + 1 ) )
#boss box check
boxes_to_check . append ( ( ( 16 + 24 , 40 + 24 , 48 , 48 ) , ( 1 , 1 ) , 1 ) )
#chaos box check
boxes_to_check . append ( ( ( 16 , 40 , 96 , 96 ) , ( 1 , 1 ) , 1 ) )
for box , coord , num in boxes_to_check :
x , y , w , h = box
subi = image . crop ( ( x , y , x + w , y + h ) )
res = cls . battle_enemies_dict . get ( to_image_key ( subi ) )
if res :
i , j = coord
enemies . append ( ( i , j , res , num ) )
enemy_count [ res ] = enemy_count . get ( res , 0 ) + 1
enemy_string = " "
for ekey in enemy_count :
enemy_string = enemy_string + " " + str ( enemy_count [ ekey ] ) + " " + ekey
enemy_string = enemy_string . strip ( )
status = [ ]
attacker = " "
defender = " "
attack_type = " "
exp_string = " "
status_text = " "
for tup , string in text :
x , y = tup
if ( 2 , 20 ) == tup :
attacker = cls . _parse_enemy_name ( string . strip ( ) )
elif ( 2 , 23 ) == tup :
defender = cls . _parse_enemy_name ( string . strip ( ) )
elif ( 2 , 26 ) == tup :
status_text = string . strip ( )
elif ( 12 , 23 ) == tup :
attack_type = string . strip ( )
elif ( 12 , 20 ) == tup :
exp_string = string . strip ( )
if " DMG " in attack_type :
attack_type = attack_type . partition ( " DMG " ) [ 0 ] + " Damage "
if attacker and defender :
if attacker . lower ( ) . strip ( ) == " exp up " and \
defender . lower ( ) . strip ( ) == " gold " :
status = [ " Exp Up: " + exp_string ]
if attack_type :
status . append ( " Gold gained: " + attack_type )
elif attacker . lower ( ) . startswith ( " lev. up! " ) and \
defender . lower ( ) . strip ( ) == " hp max " :
if attack_type . strip ( ) :
status = [ " Level up! " + attacker [ 8 : ] + " " , " HP Max: " + attack_type . partition ( " pts. " ) [ 0 ] + " points. " ]
else :
status = [ " Level up! " + attacker [ 8 : ] + " " ]
else :
if exp_string . strip ( ) and not " hits " in exp_string . lower ( ) :
status = [ attacker + " uses " + exp_string + " on " + defender ]
if attack_type :
if " DMG " in attack_type :
status . append ( attack_type . partition ( " DMG " ) [ 0 ] + " Damage " )
else :
status . append ( attack_type )
else :
status = [ attacker + " attacks " + defender ]
if attack_type :
status . append ( attack_type )
elif attacker and exp_string and attacker . strip ( ) in player_names :
status = [ attacker + " uses " + exp_string ]
if status_text :
lookup = {
" str. up " : " Strength up. " ,
" agi. up " : " Agility up. " ,
" vit. up " : " Vitality up. " ,
" int. up " : " Intelligence up. "
}
status . append ( lookup . get ( status_text . lower ( ) , status_text ) )
menu = " "
#print(text)
magic = False
for tup , string in text :
x , y = tup
if 2 < = x < = 21 and 19 < = y < = 25 :
if " > " in string :
menu = string . partition ( " > " ) [ 2 ] . strip ( ) . split ( " " ) [ 0 ]
for tup2 , string2 in text :
x2 , y2 = tup2
if y2 == y and x2 == 21 and menu :
menu + = " left " + string2
elif y2 == y and x2 < = 21 and menu and ( string2 . strip ( ) . split ( " " ) [ - 1 ] . isdigit ( ) or string2 . strip ( ) . split ( " " ) [ - 1 ] == " O " ) :
menu + = " left " + string2 . strip ( ) . split ( " " ) [ - 1 ]
elif 0 < = x < = 8 and 5 < = y < = 13 :
i = int ( x / 4 )
j = int ( ( y - 5 ) / 4 )
c = ( 3 * i + j ) + 1
for tup_x , tup_y , enemy , num in enemies :
if ( tup_x , tup_y ) == ( i , j ) :
menu = enemy + " " + str ( num )
enemy_string = " "
break
elif 15 < = x < = 20 and 6 < = y < = 18 :
if " > " in string :
if y == 6 :
menu = player_names [ 0 ] + " hp " + player_hps [ 0 ]
elif y == 9 :
menu = player_names [ 1 ] + " hp " + player_hps [ 1 ]
elif y == 12 :
menu = player_names [ 2 ] + " hp " + player_hps [ 2 ]
elif y == 15 :
menu = player_names [ 3 ] + " hp " + player_hps [ 3 ]
curr_selected = - 1
for i in range ( 4 ) :
ii = image . crop ( ( 160 , 41 + i * 24 , 168 , 41 + ( i + 1 ) * 24 ) )
if image_to_string_format ( ii , " BMP " ) != cls . empty_battle_char :
curr_selected = i
character = " "
if curr_selected > = 0 and menu . replace ( " > " , " " ) . strip ( ) in [ " Fight " , " Magic " , " Drink " , " ITEM " , " RUN " ] :
character = player_names [ curr_selected ]
#print(enemy_names, ":::")
if not menu . strip ( ) or not " " . join ( enemy_names ) . strip ( ) or " > " in " " . join ( enemy_names ) :
enemy_string = " "
if status :
enemy_string = " "
res = { " textbox " : textbox , " enemies " : enemies ,
" status " : status , " enemy_string " : enemy_string ,
" menu " : menu , " enemy_names " : enemy_names ,
" character " : character }
#print(res)
return res
@classmethod
def is_menu ( cls , image , text ) :
raw_text = " " . join ( [ x [ 1 ] for x in text ] )
#test main menu
if not raw_text :
return False
elif " CONTINUE " in raw_text and " NEW GAME " in raw_text \
and " RESPOND RATE " in raw_text :
return " main_menu "
elif cls . char_select == image_to_string_format ( image . crop ( ( 0 , 0 , image . width , 32 ) ) , " BMP " ) :
return " char_select "
elif ( " A B C D E F G H I J " in raw_text \
or " K L M N O P Q R S T " in raw_text ) \
and " SELECT NAME " in raw_text :
return " name_select "
elif " ARMOR " in raw_text and " Weapon " in raw_text and \
" Status " in raw_text :
return " player_menu "
elif " ITEM " in raw_text and text [ 0 ] [ 0 ] == ( 2 , 2 ) :
return " item_menu "
elif cls . item_sub_menu == image_to_string_format ( image . crop ( ( 0 , 0 , image . width , 92 ) ) , " BMP " ) :
return " item_sub_menu "
elif " L1 " in raw_text and " L2 " in raw_text and \
" L3 " in raw_text and " L4 " in raw_text and " L5 " in raw_text and \
" L6 " in raw_text and " L7 " in raw_text and " L8 " in raw_text and \
raw_text . count ( " / " ) > 7 :
return " magic_menu "
elif text and text [ 0 ] [ 0 ] == ( 2 , 2 ) and text [ 0 ] [ 1 ] . strip ( ) == " Weapon " :
return " weapon_menu "
elif text and text [ 0 ] [ 0 ] == ( 2 , 2 ) and text [ 0 ] [ 1 ] . strip ( ) == " ARMOR " :
return " armor_menu "
elif " EXP.POINTS " in raw_text and " FOR LEV UP " in raw_text :
return " status_menu "
elif cls . formation_menu == image_to_string_format ( image . crop ( ( 0 , 0 , image . width , 48 ) ) , " BMP " ) :
return " formation_menu "
else :
pass
#import pdb
#pdb.set_trace()
return False
@classmethod
def menu_parse ( cls , image , text ) :
menu_type = cls . is_menu ( image , text )
output = list ( )
if menu_type == " main_menu " :
for i , ( pos , entry ) in enumerate ( text ) :
if " > " in entry :
output . append ( text [ i + 1 ] [ 1 ] )
if entry . strip ( ) not in [ ' CONTINUE ' , ' NEW GAME ' ] :
output . append ( entry )
elif menu_type == " char_select " :
output = list ( )
cursor = 0
trans_dict = { " Bl.BELT " : " black belt " ,
" RedMAGE " : " red mage " ,
" Wh.MAGE " : " white mage " ,
" Bl.MAGE " : " black mage " }
for pos , entry in text :
if " >> " in entry :
if pos == ( 6 , 7 ) :
cursor = 1
elif pos == ( 20 , 7 ) :
cursor = 2
elif pos == ( 6 , 19 ) :
cursor = 3
elif pos == ( 20 , 19 ) :
cursor = 4
if cursor > 0 :
cc = 0
char_type = 0
for pos , entry in text :
if entry . strip ( ) in [ " FIGHTER " , " THIEF " , " Bl.BELT " ,
" RedMAGE " , " Wh.MAGE " , " Bl.MAGE " ] :
cc + = 1
if cursor == cc :
char_type = trans_dict . get ( entry . strip ( ) , entry )
char_type = char_type . strip ( ) . lower ( )
output . append ( " Character " + str ( cursor ) )
output . append ( char_type )
else :
chars = list ( )
pos_names = list ( )
for pos , entry in text :
if entry . strip ( ) in [ " FIGHTER " , " THIEF " , " Bl.BELT " ,
" RedMAGE " , " Wh.MAGE " , " Bl.MAGE " ] :
char_type = trans_dict . get ( entry . strip ( ) , entry )
char_type = char_type . strip ( ) . lower ( )
chars . append ( char_type )
else :
the_name = entry . strip ( )
if pos [ 1 ] == 11 and pos [ 0 ] < 20 :
pos_names . append ( [ the_name , 1 ] )
elif pos [ 1 ] == 11 and pos [ 0 ] > 20 :
pos_names . append ( [ the_name , 2 ] )
elif pos [ 0 ] < 20 :
pos_names . append ( [ the_name , 3 ] )
else :
pos_names . append ( [ the_name , 4 ] )
for i in range ( 4 ) :
for _ , c in pos_names :
if i + 1 == c :
break
else :
pos_names . append ( [ " blank " , i + 1 ] )
pos_names . sort ( key = lambda x : x [ 1 ] )
names = [ x [ 0 ] for x in pos_names ]
for i in range ( len ( names ) ) :
output . append ( chars [ i ] + " " + names [ i ] )
elif menu_type == " name_select " :
name = " "
current_char = " "
lookup = { " ' " : " apostrophe " , " , " : " comma " , " . " : " period " ,
" " : " space " , " - " : " dash " , " .. " : " dot dot " ,
" ! " : " exclamation mark " , " ? " : " question mark " }
for pos , entry in text :
if pos [ 1 ] == 3 :
name = entry [ : - 2 ]
if " > " in entry :
char = entry . split ( " > " ) [ - 1 ] . split ( " " ) [ 0 ]
if char == " O " :
if pos [ 1 ] == 15 :
char = " 0 "
if char . isupper ( ) :
char = " uppercase " + char . lower ( )
elif char . islower ( ) :
char = " lowercase " + char . lower ( )
elif char . isdigit ( ) :
pass
else :
char = lookup . get ( char , char )
current_char = char
output . append ( " Input character name " )
output . append ( name )
output . append ( " selected character: " )
output . append ( current_char )
elif menu_type == " player_menu " :
orbs = 0
for x in range ( 2 ) :
for y in range ( 2 ) :
orb = image . crop ( ( 32 + x * 16 , 24 + y * 16 , 32 + 16 * ( x + 1 ) , 24 + ( y + 1 ) * 16 ) )
orb_bmp = image_to_string_format ( orb , " BMP " )
if orb_bmp != cls . empty_orb :
orbs + = 1
orbs = str ( orbs ) + " orbs "
gold = " "
menu = " "
curr = - 1
names = [ " " for x in range ( 4 ) ]
for pos , string in text :
if pos [ 1 ] == 11 and pos [ 0 ] < 8 :
gold = string . replace ( " G " , " Gold " )
if " > " in string and string . replace ( " > " , " " ) . strip ( ) :
menu = string . replace ( " > " , " " )
elif " > " in string :
if pos == ( 10 , 1 ) :
curr = 0
elif pos == ( 19 , 1 ) :
curr = 1
elif pos == ( 10 , 15 ) :
curr = 2
elif pos == ( 19 , 15 ) :
curr = 3
elif pos [ 1 ] == 2 :
if 12 < = pos [ 0 ] < = 16 :
names [ 0 ] = string . strip ( )
elif 22 < = pos [ 0 ] < = 26 :
names [ 1 ] = string . strip ( )
elif pos [ 1 ] == 16 :
if 12 < = pos [ 0 ] < = 16 :
names [ 2 ] = string . strip ( )
elif 22 < = pos [ 0 ] < = 26 :
names [ 3 ] = string . strip ( )
if not menu :
if curr > = 0 :
menu = names [ curr ]
output . extend ( [ " Player Menu " , orbs , gold , menu ] )
elif menu_type == " item_menu " :
menu = " "
for pos , string in text :
if " >> " in string :
menu = string . partition ( " >> " ) [ 2 ] . split ( " " ) [ : 2 ]
menu = " " . join ( menu ) . strip ( )
output . extend ( [ ' Item Menu ' , menu ] )
elif menu_type == " item_sub_menu " :
des = " "
seek = None
names = list ( )
hp1 = list ( )
hp2 = list ( )
curr = - 1
for pos , string in text :
if pos [ 1 ] == 12 :
if " > " in string :
curr = len ( names )
names . append ( string . strip ( ) )
elif pos [ 1 ] == 15 :
hp1 . append ( string . strip ( ) )
elif pos [ 1 ] == 16 :
hp2 . append ( string . strip ( ) . replace ( " / " , " of " ) )
if pos [ 1 ] > = 22 :
des + = string + " "
if des :
output . append ( des )
if curr > = 0 :
output . append ( names [ curr ] + " hp " + hp1 [ curr ] + " " + hp2 [ curr ] )
else :
for i in range ( 4 ) :
output . append ( names [ i ] + " " + hp1 [ i ] )
elif menu_type == " magic_menu " :
name = " "
curr = - 1
levels = [ " " for x in range ( 8 ) ]
des = " "
for pos , string in text :
if pos [ 0 ] == 3 :
if pos [ 1 ] == 2 :
name = string . strip ( )
elif " / " in string and string [ 0 ] == " L " :
num = ( pos [ 1 ] - 4 ) / 2
levels [ num ] = string . partition ( " " ) [ 2 ] . strip ( )
elif " > " in string :
curr = ( pos [ 1 ] - 4 ) / 2
magic = string . replace ( " > " , " " ) . strip ( )
elif pos [ 1 ] > = 23 :
des + = string . strip ( ) + " "
des = des . strip ( )
output . append ( name )
if des :
output . append ( des )
if curr > = 0 :
output . append ( magic + " " + levels [ curr ] . replace ( " / " , " of " ) )
else :
output . append ( " no spells available " )
elif menu_type in [ " weapon_menu " , " armor_menu " ] :
names = [ " " for x in range ( 4 ) ]
menu = " "
curr = - 1
for pos , string in text :
if pos [ 0 ] < = 7 and pos [ 1 ] in [ 6 , 12 , 18 , 24 ] :
names [ ( pos [ 1 ] - 6 ) / 6 ] = string
elif pos [ 1 ] == 2 and pos [ 0 ] > = 9 and " > " in string :
menu = string . partition ( " >> " ) [ 2 ] . split ( " " ) [ 0 ] . strip ( )
elif " > " in string :
if 6 < = pos [ 1 ] < 12 :
curr = 0
elif 12 < = pos [ 1 ] < 18 :
curr = 1
elif 18 < = pos [ 1 ] < 24 :
curr = 2
elif 24 < = pos [ 1 ] :
curr = 3
if string . replace ( " > " , " " ) [ : 2 ] == " E- " :
menu = " equiped " + string . replace ( " > " , " " ) [ 2 : ] . strip ( )
else :
menu = string . replace ( " > " , " " ) . strip ( )
output . append ( menu_type . replace ( " _ " , " " ) )
if curr > = 0 :
output . append ( names [ curr ] )
if menu :
output . append ( menu )
elif menu_type == " status_menu " :
lud = { " STR. " : " strength " , " AGL. " : " agility " ,
" INT. " : " Intelligence " , " VIT. " : " vitality " }
lud2 = { " Wh.MAGE " : " white mage " , " Bl.MAGE " : " black mage " ,
" Bl.BELT " : " black belt " , " RedMAGE " : " red mage " ,
" FOR LEV UP " : " for level up " ,
" EXP.POINTS " : " experience points " }
for pos , string in text :
if pos [ 0 ] == 24 and pos [ 1 ] == 4 :
output . append ( string . strip ( ) . replace ( " LEV " , " Level " ) )
elif pos [ 1 ] < 12 :
output . append ( lud2 . get ( string . strip ( ) , string . strip ( ) ) )
elif pos [ 0 ] < 16 :
output . append ( lud . get ( string . strip ( ) , string . strip ( ) ) )
for pos , string in text :
if pos [ 1 ] > = 12 and pos [ 0 ] > = 16 :
if " HIT " in string :
output . append ( " Hit percent " )
elif " EVADE " in string :
output . append ( " Evade percent " )
else :
output . append ( string . strip ( ) )
elif menu_type == " formation_menu " :
names = [ " " for x in range ( 4 ) ]
curr = - 1
for pos , string in text :
this_curr = - 1
if pos [ 1 ] == 7 :
this_curr = 0
if pos [ 1 ] == 11 :
this_curr = 1
if pos [ 1 ] == 15 :
this_curr = 2
if pos [ 1 ] == 19 :
this_curr = 3
if this_curr > = 0 :
names [ this_curr ] = string . replace ( " > " , " " ) . strip ( )
if " > " in string :
curr = this_curr
output . append ( " formation menu " )
if curr > - 1 :
output . append ( " position " + str ( curr + 1 ) + " " + names [ curr ] )
return output
@classmethod
def is_shop ( cls , image ) :
dd = ImageChops . difference ( image , cls . shop_image ) . convert ( " RGB " )
p = dd . resize ( ( 1 , 1 ) , resample = Image . BILINEAR ) . getpixel ( ( 0 , 0 ) )
if p [ 0 ] == 0 and p [ 1 ] == 0 and p [ 2 ] == 0 :
return True
return False
@classmethod
def shop_parse ( cls , image , text ) :
title = text [ 0 ] [ 1 ] . strip ( ) . title ( )
textbox = list ( )
for box , l in text :
if box [ 0 ] < 7 and box [ 1 ] < 18 :
textbox . append ( l . strip ( ) )
textbox = " " . join ( textbox ) . replace ( " " , " " )
if text [ 0 ] [ 1 ] . strip ( ) in [ " INN " , " CLINIC " ] :
if len ( text ) > 2 and text [ 2 ] [ 1 ] . strip ( ) == " Gold " :
textbox + = " Current " + text [ - 1 ] [ 1 ] . strip ( )
elif text [ 0 ] [ 1 ] . strip ( ) in [ ' WEAPON ' , " ARMOR " , " WMAGIC " , " BMAGIC " ,
" ITEM " ] :
if textbox . endswith ( " Gold OK? " ) :
textbox + = " Current " + text [ - 1 ] [ 1 ] . strip ( )
select_menu = " "
sx = 0
sy = 0
print ( text )
for box , l in text :
if 20 < box [ 0 ] < 30 and 2 < box [ 1 ] < 24 :
if " > " in l :
select_menu = l . replace ( " > " , " " ) . strip ( )
sx , sy = box [ 0 ] , box [ 1 ]
elif select_menu != " " and sx == 0 and sy == 0 :
sx , sy = box
select_menu = ( select_menu + " " + l ) . strip ( )
if ( sx , sy ) != ( 0 , 0 ) :
for box , l in text :
if box [ 1 ] == sy + 2 and sx < box [ 0 ] < = 29 :
select_menu = select_menu + " " + l . strip ( )
menu = " "
for box , l in text :
if 4 < box [ 0 ] < 8 and 18 < box [ 1 ] < 26 :
if " > " in l :
menu = l . replace ( " > " , " " ) . strip ( )
result = { " title " : title , " text " : textbox , " menu " : select_menu + " " + menu }
print ( result )
return result
bridge_scene = to_image_key ( ' iVBORw0KGgoAAAANSUhEUgAAAFgAAAAgCAIAAAAZhijPAAADBUlEQVR4nM1ZO47CMBCdjVIgyoiU1BwoZ1hFkU+QE3CCCCHOkANRU7JyuaJCWzg4zviTGceEfaKA2LGfx+OZ8eOr+7kCGU27Px1v9P7J0bT7TD4AAPqCxXwWuZ6A0juTj87VP7tsFS3zudNkuoPZKurSMVnqpYaRg2nmWfQFnK9Nu88uWwB4fv9m8qEZ43F2B7QSZQX1bnccmkRdQl+MnSq5ZD3RyAFALUb91mtz9lYL0/uf1Q9z39SLwwgAUEmxw7uqmiYPjRGUazyLDXVj0iE3qZhbGnDL7ueq9lbAlK4ap+UxmFhhGIF0TtMig+CaQ29am+YYp5Jid4gitjYyYj9iNB3hOVw+jO7wIeTOp8/vX+Th2WWrwxsR3fku6tIZKRCadt8UAGhSwosJ4TYEdvt37hUjZ70TbkMATHw72gqzTiHqUvRbAIBKfjaJegyxynHVccEOEE27dgalBstodOc7gDt9dOe7z9yn4+1ZbNZMOssM0ReqptB0hwPvdCiPtyfPFyYfOvwxgoJKUnx4iBSu0oMIUZfd+W6GVTuvacTNEuMRJiH3XaOSoi7NbRkOCOD6YrhuVdK+d42nA11GXvP6PnH+FeMR6takMd41PM+Hny+/QBcN/VX0nvT0Whga34e4U/Y1jdWJb/sf1y8QAnwiYwRXv1Cg6w4RugaFEqqPTT4xhuDqF+OstJIpQtcgUZpaHPHJhTXN7Lng6hf2sGHdgatraKHIhE0ssExRl7meJlQCIDD1C9RhXndg6hpaKNKgrAXxyQBUOUC2woKrBxFcXcNtBSaGOiI6/frgC13sOpKpa3Ch+eTPYjNEnQVWIOoXcboDXdfgwuSTn443ruJig6Jf/BPdQQPxWXbXMBHULxbqDsmdwuaTyBDBY/+vdAcfn7frEZBIdwjoGhSYRaSTzxqGGKmQ80WEroGB6jcr+yA+6WJECijdwdfK0zUqKerXd8IGMP7XQBIDCyzdIULXMHnqC3SgBrH5kDyCVXe6sUB3IOkaL5yON9gddKvYFe6eFp8/JVyxsafgBGkAAAAASUVORK5CYII= ' )
bridge_credits = [
( to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAABjklEQVR4nO3Y25KDIAyAYXD6/q/MXnSboUmAoGjt9P+utAshKCc3JQAAAAAAAAAAAAAAAADAUlmuSin/P+XcKOx41pqqcqWbp5dS2j6dwDKlFBlD9wk19Khvcs6q4fpWjaPZFFV5ibZv5rWCx4d8p137i4RdPqU2lU3ynuyzPVsmnkfd2ycbx777+DuWgHXwTihp1445t7xk2Kqy29sSdN68q5/4ZbNbtR550Nfb0vtwaOV6nB34w/LLc7BNuDMmUnFVDjs3YfWehg+0vNTVVRy7x0z1c2roSOE7TALcxvcOh+/NXB9DP5XH9YYn7Guexrhh97xsj4/qWoWKfE9E4rfMxk+vPSa408S/h2Zf22AT7pzTXf3zcud7QhWuN8kU7lU8fv1Xq7WgteJLEyrtyPUt/hXhdlidlNbGnx1YLce/bx5S/4wlb2rkKgsX4lNX8/otytR3m3avN7l3O9xahfctEZ3s1QjaF7afp7vEHUneRv6pUwwAAAAAAAAAAAAAAAAAAAAAAAAAAADwu/4AM1mC7+a34rIAAAAASUVORK5CYII= " ) , " And so, their journey begins... " ) ,
( to_image_key ( ' iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAABz0lEQVR4nO3Z0XaDIAyAYejp+78yu2iHEQIGjMp2/u9ix1UlCAKhDQEAAAAAcLuUUkpJ/bc4hcL59nl5VSV7sM/U0F71uei53kWMGKO9Qp8DeYscOsUpezn5XnlQnFULrz/p1KdozX5VXZ5LZRoBaufHGD9Fy1M5WD57SC1n7vq6nq36yNaxVLX/XHXc3E/5NWrZOuBznXq1+sBPDW2XuHI8eZU2N/vtRsDo/GO/3qscr7hh/y5ftGhZhtcr/D5P/bdfdKhmRvXURDn5w+KgH9cYIt8oX09Lj849F2nk6pq96jLM3TlOQYsE2tLQ1Vr8tiZ41rv+qNgNdPJ9OS0WxyebzyvvbtXTUo6l/PN2aWgnn+3UTJLLZpECDy1HXnm3XAyDufVbG7qhddho6wDjlmQFQ3l3kUGtRpmCHCsqizrcE/qGyxZfSw6+imjNnqNDOwx+0RQGx3sr7x5t/dY+Y2gVASpsCFvmfw+gTV18F+E6dcs6+XWYmhZbKd1h3HqTMbquLEj5NrS1iKmNNZq5qh1mj/v/+P8k2UEWUbu1Ay56o//0ajS5DwizrWm8S43b+Z0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgOj9pHOL9uqLofgAAAABJRU5ErkJggg== ' ) , " What awaits the Four, they do not know. " ) ,
( to_image_key ( ' iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAADsElEQVR4nO2Z0ZbrIAhFTVf//5czD5k6BAFBMUnvPfuptQqIimBLAQAAAAAAAABwKVspZd934YdtGxB3iPKPjfbvDhkQeC/v+umLjI4SWhW6HS/wybtt2vedKq4GMWu09iyi8sVzrEmwvbxtG3NC1E7/Kr7omIPWmkME/YnuqXaIKMeeA+tvyxclFDMuGWFWtN9l90eIJsdj/98CbB9aa+zNJe6gruKZ/uuILnyJ7zbGq21qj5JxiCbVfzvzd74QgqhP2V4Q21fcAVH5mp3fohfcxu8is6WL3irph2B1Oi/ON7E9bA3LcI6v0fYxxOEDMv1Dsuab4gehDrgSFj09O4jdQ8NyHkJ/AeiqemqNkAuOkkfrL/5Uw+BOaiVbTqt0zNoVCGkog06StRs1SAqi8KzEty7hvcelvwAlWJgsnU/Whr1941f6WRC78ethb/vXbtGJte5gurTQp43yqGOIm+yiLAiAp5B1wfgV3ZyGDqBlX5epzlX6bkWLob9VbOTj0dgtoumt8if/nxgI36H/Fbp++/3VlsUWRrNAuwnrkKh3uvI1pdF72PBOaLJawlLOfmv7n/4PMBS3kTEULqkFzlGa0kIm5tQetSeruPFM9vQcXZS90/5X49xotAOV0DXrgjw9ZM+MCnsWwpFheJ4iinL6up0Nuqn3zB3QNd6YxcCdZ/gN/FtE8+jL8u4UVljreguav4RvJMtO4yVmhlPiTz/YkTR0ATjlRPNoI/dln207Q5mrdit40mUx3Ro8ATRndaatBq2z6nzaHVc1elRodlYJ0bpB9MP+edZm3exNcPR3LUCUpXl0Vkgx6p7JziEe/RZk1KIpqyuqmGFA2quczxH94FGWe7+1wtl+Z0pZnBVDimjn6kIvdLuAO0lenFvWXHvM+QourQOWlg704cWj5SF1zLs46gDtMizBLW/I8QsJ0a0Pomlo21nL95111aV1gNaecp/TG7vrUNt+e5RYrxS3/cwJj64DokpDIeghLFmASR4SnRfBDtwj6oAUxBAUrQ+iiPm+7U+ne8HjyQ0Uk9K+N2o98Q74r/h7jGvz2WLmvyJa3t0dYrSL7/6GcC017Obvoj3aa35WHH/ZRlNlnjM+9s4udhNzSu393RZo5O9MCF0VWiJo7fPkh6Csp/Oxp46QXqPAZD9p7fPkL0DUCzNCuju9O7zdzuLGF9tTFuNVpZcM30UliC8zRntUYLcbcyJrYRtfuzYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgPIDXn3QrSWoYQgAAAAASUVORK5CYII= ' ) , " Each holding an Orb, that 2000 years ago shined with beauty from within. But now, only darkness. " ) ,
( to_image_key ( ' iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAACx0lEQVR4nO2b3ZqEIAiGqWfu/5bbgxqX5EcsLWu+92RnzZARQbCGCAAAAAAAAADApUzrn2VZdq3T1GOwZVlUyVb7LzDTd/anLyTsAfrxKfZIxkiLVJqHr1/ZHzjMsin5ATHnIDtMTdOULnFnghtFUDyAT/oxMPVxyiHoAJbxatt/gZlYhFmhfXihGp+QojiWZ8BjwG1cWgcAnSxc+P+2GgWsFEK84xlqvp9EZTJrPUymv1KUOq71+Xxq14nyBPmqy6vZ91dLighcJSlEtYpjMKnPIGxpaDaDEUV7x5ORl21DtrOg2tkMTs35aq7t7A9oy1CMVufCuqW4o0RmIbItOfrEQygAjKdkio9Q8s28yQC7wzg/1p/Ju60AXSv/fSjPAzjO8wAVnm7LRwJSjvX8gB/q0Xtnn4oGuAZ178lOZN/KFoI6lYhBmbU565tMsnmAVXZaUbhViLCeH0TOPwBogL67Ps7HG+7VTUTFhfynoTxljB/GXW+qG/Oi4pHMgVOWI+8F8cbgsfCB+sBXpvZYKdjZx3mpIJjFSP1nfk1uqn6eni4FVY/XB74ca1yZzlr6H8M6qrEky/5S/1m9Fhx4NCxD9tPfL1QjC2sXgtZlIr2pecC9OIKPnFPklXBmNCtPlz1lf+rzzePxilz9mytTVXU+IqKAL0/ZA95Jmv2H2mDw1VN4z4cqA5yT1/vyz7cX9cluqa0PnHooXvdIZktQNmrVIoqf+6dGq39cjqMJH8WXb1Hb3697OIVKOGJDX13ZHmnkCtTe8ixu/n1A5qoS1ZYj5/UqjsJd9oDislVjcXapuAec1KrJHuDo068SAmPjp32DJ4XXM8RD+V/mQ1rSuojXyskIcPFIh4WvcvC9oHieK+UADkLQzbQxwLGljQ2Zst8JZx9oH3zOBJAsiGHeAQAAAAAAAAAAAAAAAAAAAAAAAAAAAC/mD4+4CUHYQSVTAAAAAElFTkSuQmCC ' ) , " Come!! Start your journey! Return the light of peace to our world. " ) ,
( to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAABoUlEQVR4nO3c25KDIAyAYd3Z939l9qKzGYaQGJGDTP/vqiKmgohVpMcBAAAAAAAAAACAoc6OsVJKZfTzdNL1Kj/diZOvzYPkGSTFSdeFqqYXm79FSqnY18/iw3RZtPIXq6qJThwnvl+uLn57BRon2Nxe2iqvzDsAeasJVlZ1E52o+yvpZORz0clY6dVosfI16n8ArIqWyooXya/0eByrx7A6/WDYLvofAL8A1Wtg27cUcaxatr6x1548tOAaICX/fNCt20q34ug8wW6kmh75Ybb8sAEAAAAAmu10R+ePNxS3rLvcrG7wOLpQPHLYpaItP6t34Nvt1Hwuhzblyf7up8VL+UOD6d/0/XqELmix/S7CPJcHAAAAAAAAAADAHf3nCd99bUTP741kbtvEz7/NfGCLHha/HCKvzu+NZNaL8Q3j2SYM8a8fE25uZZs1T8OQWZLBF9ac+b1O5NGD8pMH/Ye8lmL970KXyOIY00VI8Dln2KguKH4M4pU48623abOIB76YFf+Ph7xRXwbML/W3Orq7p8u48xgAAAAAAAAAAHyXP9LOhecc41GgAAAAAElFTkSuQmCC " ) , " Programmed by Nasir " ) ,
( to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAAB+ElEQVR4nO3b23KDIBCAYez0/V+ZXjBlKHvgHBP7f1dRN4sBQxsXQwAAAAAAAAAAAMBR1950McY/2a8r70yvc1jezG+Re6o8Vrzfbs/+dMhv9wPEGKvPkDat/dUhdedivHVUHQM/zyFfpxtoGr3KPuyqbPk+mt2ZJeSeNAmoE5E6dVTxVrsWddZS2z3q7ACUHeQPhpQ7faIXet5lBay0O+HsAPTwB0Ne5i+Yl9V2D9k5AOmkR7/Czc6t+kLGz7VrTUFWuwAAAACAZ3jFz7zR+/LykPVr2Soh9NQh/pH+OoEa37yhb23GX1W7b+X+m3FNzy4Y3D8AcvaYu7kWjNnpze+p3T8AzYpKGoyhG6v9pZvb3V+SlKy/DSvUmvs74L8gAAAAAAAAAAAAPJtXHqoqSuVmzxNuoVXJsiplVbx6AtZmGK/glxmq96oPDVonUMY3H7/JZoryVsOyR6pHi6oAq3AYxGA3+3RXvNrjfn512EJ3KfTgqojF6qv/dvkhTy8fOlRM9lZFlFeoep1a8XJJ2hB1UUl51Jp81Pih/Pm19VWQ+RfXWzSWpTizhBWfBXHqW+T855aZjGZeOZmdU1D/OPVnc1z2k/Ur+a1VXH7+6TGYGQBr6aC/pDDvH13mFvo6d2N8z2I9NSBfgnNLKwEAAAAAAAAAwDP9AKeVNvQLISpVAAAAAElFTkSuQmCC " ) , " Character Design by Yositaka Amano " ) ,
( to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAABrElEQVR4nO3c23KDIBCAYe30/V+ZXjhh6LK7gAiK+b+rFpFDUEgE3DYAAAAAAAAAAAAMtc/JJoTwL9d9d8JFYDx0hMdzj5h5Ulbi+bmV5VleCCGtWPxXhG+f+ufh6YkiqTwLNVAc8gtmxR/hd3QGuUGX1aJX64wGOHoP9ZbPY8a/rd7gSM2PqXZNTr43mnQHiM9LfILpofSDdlKzUrCyro8/2YwGyAfPfnFMFrn48R/YBm/4FtQanmf98m9BAAAAAIDESr/0rOf74hfviCcf49zwOLqT9WhhUT93F+DbrXT5OFOMsdtZq/9ZjD9lmE9YLoEu6GbrDcIPn2IEAAAAAAAAAADAw5yZUbLW4Zzb3+snGxMplkdkqoZb5VS3/LXuNz43PXf9lKRVjtY1PPVLHNTlWcXyqBdEmogocGv8Sr2T8u9bBtJal866n78DrFuvdX/v6Mar2R+odlnFjZWt8VXnGyCtiXWr5qfMX0zod0G3L268YAxo3Tb9qLVTxX33RZ3VuX4QLm61TUdX5xUG6Ts3ei7SyvKoO/TVF4OIOD2NBwAAAAAAAAAAvsIfw9p6L1hAGSoAAAAASUVORK5CYII= " ) , " Scenario by Kenji Terada " ) ,
( to_image_key ( " iVBORw0KGgoAAAANSUhEUgAAAIAAAABQCAIAAABeYuqzAAABoklEQVR4nO3c0Y6DIBBAUdj0/3+ZPpgSAgyMwGDp3vOwsaiDihJbmHUOAAAAAAAAAAAApvzCWCGEPLr3jfJyVXv7qzzddyxOuYsmTrZv+vFbhBCyE7g+GpXHZWl7aa20ql1vtep5f6sCYcxrW03VR96IRXzvvUXPs74BpAsd+9MNvadRLRZtsL4B2sdndB9tcx3/yoALY5VvC1J5bIO7by/S41WNozmqRnx33FsQAAAAAEDhsK9zym/Ozv73vv9IP35wEMYDHrZvPMDazvGGhX6nAQ666Cm6oIcddtcof68HAAAAAAAAAAAAPjqjSFLmiWZkKksjibtIQZzNPJ+y3u6Wt46nel5ZXYMZNVIa7d083mxVN7934Tyfar36XaSSdvxu+nHqxqyIyUHXp8ZsvzwlttUAV0bg/Hybsr8Kwn8ZUObdzdc7ELwaTYofl+NfKWznCciuiEV2oJQ/bHrnDgSfvwOqWg2gme6hnxLSPhq7/GHraaNSfOUZjXRBaXlc9t5n2zfuaOm9Quqaymh63XqVpONZ220CAAAAAAAAAIAf9AaQOdOneYrlMwAAAABJRU5ErkJggg== " ) , " Production of Square A-Team " )
]
@classmethod
def text_box ( cls , image , text ) :
#print([x[1] for x in text])
#res =
raw_text = " " . join ( [ x [ 1 ] for x in text ] )
output = list ( )
bridge_test = image_to_string_format ( image . crop ( ( 40 , 128 , 128 , 160 ) ) , " BMP " )
if bridge_test == cls . bridge_scene :
cropped = image_to_string_format ( image . crop ( ( 40 , 32 , 168 , 112 ) ) , " BMP " )
#import pdb
#pdb.set_trace()
for cred , t in cls . bridge_credits :
if cred == cropped :
output = [ ( ( 1 , 1 ) , t ) ]
break
else :
for pos , entry in text :
for r1 , r2 in [ ( " ORBS " , " Orbs " ) , ( " ORB " , " Orb " ) , ( " G0 " , " Go " ) ,
( " g0 " , " go " ) ] :
entry = entry . replace ( r1 , r2 )
output . append ( ( pos , entry ) )
return [ x [ 1 ] for x in output ]
def main3 ( ) :
import os
screen_test_list = list ( )
ScreenSelector . _load_content ( None , None , None , None )
for filename in os . listdir ( " ./ " ) :
if filename . startswith ( " test_ " ) :
if " battle " in filename :
screen_test_list . append ( filename )
for i , name in enumerate ( sorted ( screen_test_list , key = lambda x : int ( x . partition ( " battle " ) [ 2 ] . partition ( " . " ) [ 0 ] ) ) ) :
if i < 50 :
continue
image = Image . open ( name )
print ( name )
ScreenSelector . parse_whole_screen ( image )
import pdb
pdb . set_trace ( )
def main2 ( ) :
image_list = [ Image . open ( " text " + str ( i ) + " .png " ) for i in range ( 7 ) ]
f = ParseScreenText . get_font ( image_list )
start_image_id = ObjectId ( " 5df9d8208ac3d956387c0941 " )
doc = db . ocr_images . find_one ( { " _id " : start_image_id } )
game_id = doc [ ' game_id ' ]
user_id = doc [ ' user_id ' ]
for image in db . ocr_images . find ( { " user_id " : user_id ,
" game_id " : game_id } ,
sort = [ ( " _id " , pymongo . ASCENDING ) ] ) :
im = load_image ( image [ ' image_data ' ] )
t = time . time ( )
tex = ParseScreenText . parse_screen ( im , f )
2024-08-06 12:41:40 -04:00
print ( ( time . time ( ) - t ) )
2024-08-05 13:41:50 -04:00
for coord , line in tex :
2024-08-06 12:41:40 -04:00
print ( ( coord , line ) )
2024-08-05 13:41:50 -04:00
if tex :
import pdb
pdb . set_trace ( )
def main4 ( ) :
image_list = [ Image . open ( " text " + str ( i ) + " .png " ) for i in range ( 7 ) ]
f = ParseScreenText . get_font ( image_list )
start_image_id = ObjectId ( " 5df9d8208ac3d956387c0941 " )
doc = db . ocr_images . find_one ( { " _id " : start_image_id } )
game_id = doc [ ' game_id ' ]
user_id = doc [ ' user_id ' ]
c = 0
enemy_data = {
" iguana " : { " w " : 48 } ,
" garland " : { " x " : 64 , " y " : 72 , " ratio " : 0.5 } ,
" asp " : { " ratio " : 0.5 } ,
" agama " : { " w " : 48 } ,
" badman " : { " x " : 64 } ,
" evilman " : { " x " : 64 } ,
" bull " : { " x " : 16 , " y " : 40 , " w " : 48 , " h " : 48 } ,
" hyena " : { " x " : 80 } ,
" seasnake " : { " w " : 32 , " ratio " : 0.5 } ,
" naga " : { " w " : 48 , " ratio " : 0.5 } ,
" grnaga " : { " w " : 48 , " ratio " : 0.5 } ,
" wzvamp " : { " w " : 48 , " w " : 32 , " ratio " : 0.25 } ,
" kary " : { " ratio " : 0.05 , " ratio2 " : 0.95 , " w " : 96 } ,
" kraken " : { " ratio " : 0.05 , " ratio2 " : 0.95 , " w " : 96 } ,
" tiamat " : { " ratio " : 0.05 , " ratio2 " : 0.95 , " w " : 96 } ,
" medusa " : { " x " : 64 } ,
" warmech " : { " w " : 48 } ,
" vampire " : { " x " : 64 , " w " : 32 } ,
" wzvamp " : { " x " : 64 , " w " : 32 } ,
" zombull " : { " x " : 16 , " y " : 40 , " w " : 48 , " h " : 48 } ,
" r.ankylo " : { " w " : 48 } ,
" r.giant " : { " w " : 48 } ,
" r.hydra " : { " w " : 48 } ,
" wrwolf " : { " x " : 96 , " ratio " : 0.5 } ,
}
for filename in os . listdir ( " ./ " ) :
if " enemy " in filename :
if filename . split ( " . " ) [ 0 ] . split ( " _ " ) [ - 1 ] . isdigit ( ) :
os . remove ( filename )
found = dict ( )
saved = dict ( )
for image in db . ocr_images . find ( { " user_id " : user_id ,
" game_id " : game_id } ,
sort = [ ( " _id " , pymongo . ASCENDING ) ] ) :
im = load_image ( image [ ' image_data ' ] )
if ScreenSelector . is_battle ( im ) :
text = ParseScreenText . parse_screen ( im , f )
res = ScreenSelector . battle_parse ( im , text )
if not res . get ( " status " ) and res . get ( " menu " ) . lower ( ) in [ ' fight ' , ' magic ' , ' item ' , ' drink ' , ' run ' ] and len ( res . get ( " enemy_names " , [ ] ) ) == 1 :
name = res [ ' enemy_names ' ] [ 0 ] . strip ( ) . lower ( )
found [ name ] = 1
boxes_to_check = list ( )
#check 3x3
for i in range ( 3 ) :
for j in range ( 3 ) :
x = 16 + 32 * i
y = 40 + 32 * j
w = 32
h = 32
boxes_to_check . append ( ( x , y , w , h ) )
#check for big enemy plus 3 small
for i in range ( 1 ) :
for j in range ( 3 ) :
x = 16 + 48
y = 40 + 32 * j
w = 32
h = 32
boxes_to_check . append ( ( x , y , w , h ) )
for i in range ( 3 ) :
for j in range ( 3 ) :
x = 32 + 32 * i
y = 40 + 32 * j
w = 32
h = 32
boxes_to_check . append ( ( x , y , w , h ) )
#check for big enemies
for i in range ( 2 ) :
for j in range ( 2 ) :
x = 16 + 48 * i
y = 40 + 48 * j
w = 48
h = 48
boxes_to_check . append ( ( x , y , w , h ) )
for i in range ( 1 ) :
for j in range ( 2 ) :
x = 80
y = 40 + 48 * j
w = 48
h = 48
boxes_to_check . append ( ( x , y , w , h ) )
#boss box check
boxes_to_check . append ( ( 16 + 24 , 40 + 24 , 48 , 48 ) )
#chaos box check
boxes_to_check . append ( ( 16 , 40 , 96 , 96 ) )
for i in range ( 2 ) :
if i == 1 :
ratio = 0.25
else :
ratio = 0.75
for x , y , w , h in boxes_to_check :
flag = False
for ch in " xywh " :
var = locals ( ) [ ch ]
if enemy_data . get ( name , { } ) . get ( ch , var ) != var :
break
else :
flag = True
if flag is False :
continue
subi = im . crop ( ( x , y , x + w , y + h ) )
lines = [ subi . crop ( ( 0 , 0 , 1 , h ) ) ,
subi . crop ( ( 0 , 0 , w , 1 ) ) ,
subi . crop ( ( w - 1 , 0 , w , h ) ) ,
subi . crop ( ( 0 , h - 1 , w , h ) ) ]
flag = False
for line in lines :
for cc in line . convert ( " RGBA " ) . getcolors ( ) :
amt = h * enemy_data . get ( name , { } ) . get ( " ratio " , ratio )
if cc [ 1 ] == ( 0 , 0 , 0 , 255 ) and cc [ 0 ] > amt :
break
else :
#this line did not have enough black pixels
print ( " not enough black pixels " )
break
else :
#all the lines had enough black pixels.
flag = True
if flag is False :
continue
p = subi . convert ( " RGB " ) . resize ( ( 1 , 1 ) , resample = Image . BILINEAR ) . getpixel ( ( 0 , 0 ) )
if not p [ 0 ] and not p [ 1 ] and not p [ 2 ] :
continue
ratio2 = 85 / 100.0
if enemy_data . get ( name , { } ) . get ( " ratio2 " ) :
ratio2 = enemy_data [ name ] [ ' ratio2 ' ]
for cc in subi . convert ( " RGB " ) . getcolors ( ) :
if cc [ 1 ] == ( 0 , 0 , 0 ) :
if cc [ 0 ] < ratio2 * w * h :
#succ
break
else :
#fail
continue
else :
#fail
continue
i = 0
saved [ name ] = 1
while True :
filename = " enemy_ " + name + " _ " + str ( i ) + " .png "
try :
old_im = Image . open ( filename )
if image_to_string_format ( old_im , " BMP " ) == image_to_string_format ( subi , " BMP " ) :
break
else :
i + = 1
except :
subi . save ( filename )
break
break
if name in saved :
break
im . save ( " test_battle " + str ( c ) + " .png " )
c + = 1
for key in found :
if key not in saved :
print ( [ ' not found ' , key ] )
def test_person ( ) :
im = Image . open ( " person_test.png " )
po = PackageOutput ( " ff1_data.lud " , " enemy_lookup.dat " )
import pdb
pdb . set_trace ( )
2024-08-06 12:41:40 -04:00
print ( ( " -- " , po . memory ) )
print ( ( po . run ( im , { " paused " : 1 } ) ) )
2024-08-05 13:41:50 -04:00
if __name__ == ' __main__ ' :
#main4()
#main3()
#main2()
main ( )
#main_c()
#test_person()