#! /usr/bin/python3
# ==================================================================
# 3D Matrix Game - Load Matrix Definition File
# ==================================================================
import game_matrix_config as cfg
import game_matrix_menu as mnu
import game_matrix01 as gm1
# ---- global data -------------------------------------------------
# CurrentNode matrix current (working) node
# Debug flag - print debug messages
# EndNode matrix path end node
# MatrixEdge nodes per matrix dimensions (x,y,z)
# StartNode matrix path start node
# Verbose flag - print verbose messages
# ------------------------------------------------------------------
global CurrentNode
global Debug
global EndNode
global MatrixEdge
global StartNode
global Verbose
# ----- matrix definition file data --------------------------------
#
# ------------------------------------------------------------------
df_current_node = None
df_end_node = None
df_matrix_edge = None
df_node = []
df_start_node = None
df_wormhole = []
# ---- local data --------------------------------------------------
# directions allowed movement directions
# ------------------------------------------------------------------
directions = [ 'forward', 'backward', 'left', 'right',
'up', 'down' ]
# ---- matrix definition file error message ------------------------
def def_file_error(lcount,line):
'''
Display matrix definition file error message.
'''
mnu.clear_screen()
print('=======================================================')
print('Error in matrix definition file\n(line={}) ({})'.
format(lcount,line))
print('=======================================================')
mnu.pause_program()
# ---- matrix definition internal error ----------------------------
def df_file_internal_error(mgs):
mnu.clear_screen()
print('=======================================================')
print('Internal Error')
print('{}'.format(msg))
print('=======================================================')
mnu.pause_program()
# ---- convert string to integer -----------------------------------
def convert_str_to_int(str,lcount,line):
'''
Convert string to integer.
Return integer if ok or None if an error.
'''
sstr = str.strip()
if sstr == '':
def_file_error(lcount,line)
return None
if sstr.isdigit() != True:
def_file_error(lcount,line)
return None
return int(sstr)
# ---- process matrixedge ------------------------------------------
def process_matrixedge(llist,lcount,line):
'''
Process matrix edge definition.
Return True if ok or False if an error.
'''
# ---- matrix edge parameters
if len(llist) != 2:
def_file_error(lcount,line)
return False
# ---- matrixside length
l = convert_str_to_int(llist[1],lcount,line)
if l == None:
return False
# ---- save data
global df_matrix_edge
df_matrix_edge = l
return True
# ---- process startnode -------------------------------------------
def process_startnode(llist,lcount,line):
'''
Process start node definition.
Return True if ok or False if an error.
'''
# ---- start node parameters
if len(llist) != 4:
def_file_error(lcount,line)
return False
# ---- start node coordinates
x = convert_str_to_int(llist[1],lcount,line)
if x == None:
return False
y = convert_str_to_int(llist[2],lcount,line)
if y == None:
return False
z = convert_str_to_int(llist[3],lcount,line)
if z == None:
return False
# ---- save data
global df_start_node
df_start_node = (x,y,z)
return True
# ---- process endnode ---------------------------------------------
def process_endnode(llist,lcount,line):
'''
Process end node definition.
Return True if ok or False if an error.
'''
# ---- end node parameters
if len(llist) != 4:
def_file_error(lcount,line)
return False
# ---- end node coordinates
x = convert_str_to_int(llist[1],lcount,line)
if x == None:
return False
y = convert_str_to_int(llist[2],lcount,line)
if y == None:
return False
z = convert_str_to_int(llist[3],lcount,line)
if z == None:
return False
# ---- save data
global df_end_node
df_end_node = (x,y,z)
return True
# ---- process currentnode -----------------------------------------
def process_currentnode(llist,lcount,line):
'''
Process current node definition.
Return True if ok or False if an error.
'''
# ---- current node parameters
if len(llist) != 4:
def_file_error(lcount,line)
return False
# ---- current node coordinates
x = convert_str_to_int(llist[1],lcount,line)
if x == None:
return False
y = convert_str_to_int(llist[2],lcount,line)
if y == None:
return False
z = convert_str_to_int(llist[3],lcount,line)
if z == None:
return False
# ---- save data
global df_current_node
df_current_node = (x,y,z)
return True
# ---- process wormhole --------------------------------------------
def process_wormhole(llist,lcount,line):
'''
Process wormhole definition.
Return True if ok or False if an error.
'''
# ---- wormhole parameters
if len(llist) < 7:
def_file_error(lcount,line)
return False
# ---- wormhole source node coordinates
sx = convert_str_to_int(llist[1],lcount,line)
if sx == None:
return False
sy = convert_str_to_int(llist[2],lcount,line)
if sy == None:
return False
sz = convert_str_to_int(llist[3],lcount,line)
if sz == None:
return False
# ---- wormhole destination node coordinates
dx = convert_str_to_int(llist[4],lcount,line)
if dx == None:
return False
dy = convert_str_to_int(llist[5],lcount,line)
if dy == None:
return False
dz = convert_str_to_int(llist[6],lcount,line)
if dz == None:
return False
# --- test for one way / two way
if len(llist) < 7:
w = 'oneway'
elif llist[7] == 'oneway':
w = 'oneway'
elif llist[7] == 'twoway':
w = 'twoway'
else:
def_file_error(lcount,line)
return False
# --- save data
global def_wormhole
df_wormhole.append((sx,sy,sz,dx,dy,dz,w))
return True
# ---- process node ------------------------------------------------
def process_node(llist,lcount,line):
'''
Process node definition.
Return True if ok or False if an error.
'''
# ---- node parameters
if len(llist) < 5:
def_file_error(lcount,line)
return False
# ---- node coordinates
x = convert_str_to_int(llist[1],lcount,line)
if x == None:
return False
y = convert_str_to_int(llist[2],lcount,line)
if y == None:
return False
z = convert_str_to_int(llist[3],lcount,line)
if z == None:
return False
# ---- movement direction
d = llist[4]
if d not in directions:
def_file_error(lcount,line)
return False
# --- test for one way / two way
if len(llist) < 6:
w = 'oneway'
elif llist[5] == 'oneway':
w = 'oneway'
elif llist[5] == 'twoway':
w = 'twoway'
else:
def_file_error(lcount,line)
return False
# ---- save data
global df_wormhole
df_node.append((x,y,z,d,w))
return True
# ---- read matrix definition file ---------------------------------
def read_matrix_definition(filename):
'''
Read a matrix definition file and save the data.
Return True if successful and False if not.
'''
if cfg.Debug:
print('read_matrix_definition({})'.format(filename))
# ---- initialize matrix definition data
df_current_node = None
df_end_node = None
df_matrix_edge = None
df_node = []
df_start_node = None
df_wormhole = []
# ---- open matrix definition file
inFile = open(filename,'r')
# ---- process each line of the file
lcount = 0
for line in inFile:
lcount += 1
# ---- strip leading and trailing whitespace
sline = line.strip()
##print(sline)
##print('line type={} len={}'.format(type(sline),len(sline)))
# ---- blank line?
if not sline:
##print('blank line')
continue
# ---- comment line?
# ---- (first non-space char is '#')
if sline[0][:1] == '#':
##print('comment line')
continue
# ---- split line
llist = sline.split()
# ---- process line
if cfg.Debug:
print(llist)
if llist[0] == 'matrixedge':
if process_matrixedge(llist,lcount,line) == False:
inFile.close()
return False
elif llist[0] == 'startnode':
if process_startnode(llist,lcount,line) == False:
inFile.close()
return False
elif llist[0] == 'endnode':
if process_endnode(llist,lcount,line) == False:
inFile.close()
return False
elif llist[0] == 'currentnode':
if process_currentnode(llist,lcount,line) == False:
inFile.close()
return False
elif llist[0] == 'node':
if process_node(llist,lcount,line) == False:
inFile.close()
return False
elif llist[0] == 'wormhole':
if process_wormhole(llist,lcount,line) == False:
inFile.close()
return False
else:
def_file_error(lcount,line)
inFile.close()
return False
# ---- close input file
inFile.close()
return True
# ---- read matrix definition file ---------------------------------
def load_matrix_definition(filename):
'''
Load a matrix definition file's data and create the matrix.
Return the matrix if successful and None if not.
'''
# ---- read matrix definition file
if read_matrix_definition(filename) != True:
return False
# ---- create matrix
mtrx = gm1.create_matrix(df_matrix_edge,100)
if mtrx == None:
return False
# ---- add path nodes
for n in df_node:
x = n[0]
y = n[1]
z = n[2]
d = n[3]
w = n[4]
if w != 'oneway' and w != 'twoway':
msg = 'bad twoway direction ({})'.format(w)
df_file_internal_error(msg)
return None
if d == 'forward':
mtrx[x][y][z].forward = mtrx[x][y][z+1]
if w == 'twoway':
mtrx[x][y][z+1].backward = mtrx[x][y][z]
elif d == 'backward':
mtrx[x][y][z].backward = mtrx[x][y][z-1]
if w == 'twoway':
mtrx[x][y][z-1].forward = mtrx[x][y][z]
elif d == 'up':
mtrx[x][y][z].up = mtrx[x][y+1][z]
if w == 'twoway':
mtrx[x][y+1][z].down = mtrx[x][y][z]
elif d == 'down':
mtrx[x][y][z].down = mtrx[x][y-1][z]
if w == 'twoway':
mtrx[x][y-1][z].up = mtrx[x][y][z]
elif d == 'left':
mtrx[x][y][z].left = mtrx[x-1][y][z]
if w == 'twoway':
mtrx[x-1][y][z].right = mtrx[x][y][z]
elif d == 'right':
mtrx[x][y][z].right = mtrx[x+1][y][z]
if w == 'twoway':
mtrx[x+1][y][z].left = mtrx[x][y][z]
else:
msg = 'bad node movement direction ({})'.format(d)
df_file_internal_error(msg)
return None
# ---- add path wormholes
for w in df_wormhole:
sx = w[0]
sy = w[1]
sz = w[2]
ex = w[3]
ey = w[4]
ez = w[5]
ww = w[6]
mtrx[sx][sy][sz].wormhole = mtrx[ex][ey][ez]
if ww == 'twoway':
mtrx[ex][ey][ez].wormhole = mtrx[sx][sy][sz]
# ---- update configuration information
cfg.MatrixEdge = df_matrix_edge
x = df_current_node[0]
y = df_current_node[1]
z = df_current_node[2]
cfg.CurrentNode = mtrx[x][y][z]
x = df_start_node[0]
y = df_start_node[1]
z = df_start_node[2]
cfg.StartNode = mtrx[x][y][z]
x = df_end_node[0]
y = df_end_node[1]
z = df_end_node[2]
cfg.EndNode = mtrx[x][y][z]
# ---- return matrix
return mtrx
# ------------------------------------------------------------------
# ---- main --------------------------------------------------------
# ------------------------------------------------------------------
if __name__ == '__main__':
cfg.Debug = True
##filename = 'game_matrix_01.txt'
filename = 'game_matrix_02.txt'
##filename = 'game_matrix_03.txt'
load_matrix_definition(filename)
print('EOF')
print('\n---- Definition File Data -----------------')
print('df_matrix_edge = {}'.format(df_matrix_edge))
print('df_current_node = {}'.format(df_current_node))
print('df_end_node = {}'.format(df_end_node))
print('df_start_node = {}'.format(df_start_node))
print('df_node (len={})'.format(len(df_node)))
for x in df_node:
print(' node {}'.format(x))
print('df_wormhole (len={})'.format(len(df_wormhole)))
for x in df_wormhole:
print(' wormhole {}'.format(x))