diff --git a/proj/main.py b/proj/main.py index 753b59f..f372972 100644 --- a/proj/main.py +++ b/proj/main.py @@ -5,6 +5,8 @@ import copy MAP_POS_X = 16 MAP_POS_Y = 2 +WEAPON_SPEED = 1 + PLAYER = 'P' MONSTER = 'M' EMPTY = ' ' @@ -13,7 +15,9 @@ MARK = '!' WALL = '#' GOLD = '$' WEAPON = '/' +ACTIVE_WEAPON = '.' ADD_HEALTH = '+' +SCORE = '@' SIMPLE_COLOR = 1 ACTIVE_COLOR = 2 @@ -25,12 +29,36 @@ PLAYER_COLOR = 7 DOOR_COLOR = 8 MONSTER_COLOR = 9 ADD_HEALTH_COLOR = 10 +SCORE_COLOR = 11 +ACTIVE_WEAPON_COLOR = 12 + +MONSTER_DAMAGE = 1 + +P_POS = 0 +P_HEALTH = 1 +P_WEAPON = 2 +P_GOLD = 3 +P_ACTIVE_DOOR = 4 +P_SCORE = 5 + +MOVE_UP_ACTION = "KEY_UP" +MOVE_DOWN_ACTION = "KEY_DOWN" +MOVE_LEFT_ACTION = "KEY_LEFT" +MOVE_RIGHT_ACTION = "KEY_RIGHT" + +ATTACK_UP_ACTION = 'w' +ATTACK_DOWN_ACTION = 's' +ATTACK_LEFT_ACTION = 'a' +ATTACK_RIGHT_ACTION = 'd' + +NEXT_DOOR_ACTION = 'q' +PREV_DOOR_ACTION = 'e' DIRECTIONS = [ - [1, 0], - [-1, 0], + [0, -1], [0, 1], - [0, -1] + [-1, 0], + [1, 0] ] EXTENDED_DIRECTIONS = DIRECTIONS + [ @@ -61,6 +89,8 @@ def begin_curses(): curses.init_pair(DOOR_COLOR, curses.COLOR_BLUE, curses.COLOR_BLACK) curses.init_pair(MONSTER_COLOR, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(ADD_HEALTH_COLOR, curses.COLOR_GREEN, curses.COLOR_BLACK) + curses.init_pair(SCORE_COLOR, curses.COLOR_GREEN, curses.COLOR_BLACK) + curses.init_pair(ACTIVE_WEAPON_COLOR, curses.COLOR_YELLOW, curses.COLOR_BLACK) return stdscr @@ -81,12 +111,12 @@ def gen_map_step(map): for j in range(1, len(map[i]) - 1): x = 0 for d in EXTENDED_DIRECTIONS: - if tmp_map[i][j] == WALL: + if tmp_map[i + d[0]][j + d[1]][0] == WALL: x += 1 if x < 2 or x >= 4: - map[i][j] = (EMPTY, SIMPLE_COLOR) - elif x == 3: - map[i][j] = (WALL, WALL_COLOR) + map[i][j] = [EMPTY, SIMPLE_COLOR] + elif x >= 3 and x <= 3: + map[i][j] = [WALL, WALL_COLOR] def generate_map(map, sz_x, sz_y, map_symbols, @@ -176,7 +206,7 @@ def move_monsters(map, monsters): pos = [0, 0] pos[0] = monsters[i][0][0] + monsters[i][1][0] pos[1] = monsters[i][0][1] + monsters[i][1][1] - if map[pos[0]][pos[1]][0] == EMPTY: + if map[pos[0]][pos[1]][0] != WALL: monsters[i][0] = pos pass else: @@ -186,8 +216,8 @@ def move_monsters(map, monsters): def damage_player(monsters, player_state): for m in monsters: - if abs(player_state[0][0] - m[0][0]) + abs(player_state[0][1] - m[0][1]) <= 1: - player_state[1] -= 1 + if abs(player_state[P_POS][0] - m[0][0]) + abs(player_state[P_POS][1] - m[0][1]) <= 1: + player_state[P_HEALTH] -= MONSTER_DAMAGE pass @@ -198,20 +228,41 @@ def game_step(map, monsters, player_state, doors): pass -def draw(stdscr, map, monsters, player_state): - if player_state[1] <= 0: - stdscr.addstr(max(curses.COLS // 2 - 4, 0), - max(curses.LINES // 2 - 4, 0), "You lose(") - return +def draw(stdscr, map, monsters, active_weapon, player_state): + stdscr.addstr(0, 0, str(player_state)) - stdscr.addstr(MAP_POS_Y - 1, 0, "Lives: " + str(player_state[1]), - curses.color_pair(HIGHLIGHTED_COLOR)) + info_str = [ + "Health: " + str(player_state[P_HEALTH]), + "Weapon: " + str(player_state[P_WEAPON]), + "Gold: " + str(player_state[P_GOLD]), + "", + "Help:", + "", + "ARROWS - move", + "", + "WASD - use", + "weapon", + "", + "QE - move", + "through doors", + "", + "You must", + "collect", + "all score", + "", + "% - weapon", + "# - wall", + "@ - score", + "M - monster", + "P - player", + "> - door", + "$ - money", + "+ - add health" + ] - stdscr.addstr(MAP_POS_Y, 0, "Weapon: " + str(player_state[2]), - curses.color_pair(HIGHLIGHTED_COLOR)) - - stdscr.addstr(MAP_POS_Y + 1, 0, "Gold: " + str(player_state[3]), - curses.color_pair(HIGHLIGHTED_COLOR)) + for i in range(len(info_str)): + stdscr.addstr(MAP_POS_Y - 1 + i, 0, info_str[i], + curses.color_pair(HIGHLIGHTED_COLOR)) for i in range(len(map)): stdscr.addstr(MAP_POS_Y - 1, i + MAP_POS_X, @@ -228,35 +279,40 @@ def draw(stdscr, map, monsters, player_state): for i in range(len(map)): for j in range(len(map[i])): stdscr.addstr(j + MAP_POS_Y, i + MAP_POS_X, - map[i][j][0], curses.color_pair(map[i][j][1])) + map[i][j][0], curses.color_pair(map[i][j][1])) for m in monsters: stdscr.addstr(m[0][1] + MAP_POS_Y, m[0][0] + MAP_POS_X, MONSTER, curses.color_pair(MONSTER_COLOR)) - stdscr.addstr(MAP_POS_Y + player_state[0][1], - MAP_POS_X + player_state[0][0], PLAYER, + for w in active_weapon: + stdscr.addstr(w[0][1] + MAP_POS_Y, w[0][0] + MAP_POS_X, + ACTIVE_WEAPON, curses.color_pair(ACTIVE_WEAPON_COLOR)) + + stdscr.addstr(MAP_POS_Y + player_state[P_POS][1], + MAP_POS_X + player_state[P_POS][0], PLAYER, curses.color_pair(PLAYER_COLOR)) def input(stdscr): # not work m = [0, 0] + key = "" try: key = stdscr.getkey() - if key == 'w' or key == "KEY_UP": + if key == MOVE_UP_ACTION: m[1] -= 1 - elif key == 's' or key == "KEY_DOWN": + elif key == MOVE_DOWN_ACTION: m[1] += 1 - elif key == 'a' or key == "KEY_LEFT": + elif key == MOVE_LEFT_ACTION: m[0] -= 1 - elif key == 'd' or key == "KEY_RIGHT": + elif key == MOVE_RIGHT_ACTION: m[0] += 1 except: pass # no input - return m + return (m, key) pass @@ -271,60 +327,144 @@ def move_player(map, player_state, pos_change): if x != WALL: player_state[0] = p if x == ADD_HEALTH: - player_state[1] += 1 - map[p[0]][p[1]] = [EMPTY, SIMPLE_COLOR] + player_state[P_HEALTH] += 1 elif x == WEAPON: - player_state[2] += 1 - map[p[0]][p[1]] = [EMPTY, SIMPLE_COLOR] + player_state[P_WEAPON] += 1 elif x == GOLD: - player_state[3] += 1 + player_state[P_GOLD] += 1 + elif x == SCORE: + player_state[P_SCORE] += 1 + + if x != WALL and x != DOOR: + map[p[0]][p[1]] = [EMPTY, SIMPLE_COLOR] + + +def use_weapon(map, active_weapon, player_state, direction): + p = copy.deepcopy(player_state[P_POS]) + p[0] += direction[0] + p[1] += direction[1] + if map[p[0]][p[1]][0] == WALL: + if p[0] != 0 and p[1] != 0 and p[0] != len(map) - 1 and p[1] != len(map[0]): map[p[0]][p[1]] = [EMPTY, SIMPLE_COLOR] + else: + active_weapon.append([p, copy.deepcopy(direction)]) + + +def player_actions(map, doors, active_weapon, player_state, player_action): + if doors[player_state[P_ACTIVE_DOOR]]: + if player_action == NEXT_DOOR_ACTION: + player_state[P_ACTIVE_DOOR] += 1 + player_state[P_ACTIVE_DOOR] %= len(doors) + player_state[P_POS] = copy.deepcopy( + doors[player_state[P_ACTIVE_DOOR]]) + elif player_action == PREV_DOOR_ACTION: + player_state[P_ACTIVE_DOOR] = (player_state[P_ACTIVE_DOOR] + + len(doors) - 1) % len(doors) + player_state[P_POS] = copy.deepcopy( + doors[player_state[P_ACTIVE_DOOR]]) + k = -1 + if player_action == ATTACK_UP_ACTION: + k = 0 + elif player_action == ATTACK_DOWN_ACTION: + k = 1 + elif player_action == ATTACK_LEFT_ACTION: + k = 2 + elif player_action == ATTACK_RIGHT_ACTION: + k = 3 + + if k >= 0: + use_weapon(map, active_weapon, player_state, DIRECTIONS[k]) + + + +def move_weapon(map, active_weapon, player_state): # needed to test + remove_list = [] + for i in range(len(active_weapon)): + p = copy.deepcopy(active_weapon[i][0]) + p[0] += active_weapon[i][1][0] + p[1] += active_weapon[i][1][1] + if map[p[0]][p[1]][0] == WALL or \ + map[p[0]][p[1]][0] == DOOR: + p = active_weapon[i][0] + if map[p[0]][p[1]][0] == SCORE: + player_state[P_SCORE] += 1 + map[p[0]][p[1]] = [WALL, WALL_COLOR] + remove_list.append(i) + else: + active_weapon[i][0] = p + + for i in remove_list: + active_weapon.remove(active_weapon[i]) + + +def calc_max_score(map): + max_score = 0 + for row in map: + for cell in row: + if cell[0] == SCORE: + max_score += 1 + return max_score def main(): map_symbols = [ - [[EMPTY, SIMPLE_COLOR], 30], - [[WALL, WALL_COLOR], 10], - [[GOLD, GOLD_COLOR], 1], - [[WEAPON, WEAPON_COLOR], 2], - [[ADD_HEALTH, ADD_HEALTH_COLOR], 1] + [[EMPTY, SIMPLE_COLOR], 90], + [[GOLD, GOLD_COLOR], 2], + [[WEAPON, WEAPON_COLOR], 4], + [[ADD_HEALTH, ADD_HEALTH_COLOR], 2], + [[SCORE, SCORE_COLOR], 2] ] stdscr = begin_curses() - map_size = [20, 20] + map_size = [40, 20] - player_state = [[0, 0], 10, 0, 0] # pos, lives, weapon, money + active_weapon = [] # positions of active weapon map = [] - generate_map(map, map_size[0], map_size[1], map_symbols, 100, 100, 45) + generate_map(map, map_size[0], map_size[1], map_symbols, 20, 100, 45) doors = generate_doors(map) - player_state[0] = doors[0] + monsters = generate_monsters(map, 100, 3) - monsters = generate_monsters(map, 100, 7) + max_score = calc_max_score(map) + + player_state = [doors[0], 10, 2, 0, 0, 0] + # pos = [x, y], lives, weapon, money, active door, score main_loop_exception = False - #try: - while(True): - stdscr.clear() - game_step(map, monsters, player_state, doors) - draw(stdscr, map, monsters, player_state) - stdscr.refresh() - pos_change = input(stdscr) - move_player(map, player_state, pos_change) - #time.sleep(0.1) + player_win = False - #except: - # main_loop_exception = True + try: + while(True): + stdscr.clear() + game_step(map, monsters, player_state, doors) + draw(stdscr, map, monsters, active_weapon, player_state) + stdscr.refresh() + pos_change, player_action = input(stdscr) + move_player(map, player_state, pos_change) + player_actions(map, doors, active_weapon, player_state, player_action) + for i in range(WEAPON_SPEED): + move_weapon(map, active_weapon, player_state) + if player_state[P_HEALTH] <= 0: + break + if player_state[P_SCORE] == max_score: + player_win = True + break # win + except: + main_loop_exception = True end_curses(stdscr) if main_loop_exception: - print("Error during main loop"); + print("Error during main loop") + elif player_win: + print("You win!") + else: + print("You lose(") main()