/* $Id: map.h,v 1.65 2019/08/15 10:41:53 kili Exp $ */
/*
* Copyright (c) 2016, 2017 Matthias Kilian
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef TRISOLD_MAP_H
#define TRISOLD_MAP_H
#include "canvas.h"
#include "moves.h"
#define MAP_MAX 496 /* Maximum height and width */
struct move_list {
struct move *mv;
struct move_list *next;
};
struct map {
short w;
short h;
int cps; /* bitmap of checkpoints */
char *fname; /* Filename of map input */
char *fields;
short *dnfs; /* Distances to nearest finish */
struct move_arr **moves;
/* Heads of lists of finish and start moves: */
struct move_list *finfirst;
struct move_list *stafirst;
struct map_stat *st;
};
struct map_stat {
unsigned long tcount; /* total move count */
unsigned long rcount; /* real move count */
unsigned long ccount; /* total costs count */
unsigned long ucount; /* unresolved start moves */
/* There was also a vcount for the number of valid moves, but
* that's now directly returned by calc_moves(), regardless
* wether statistics are collected or not.
*/
short max1r_x; /* Start of the first */
short max1r_y; /* "fastest" real move found. */
short max1r_dx; /* Delta of the first */
short max1r_dy; /* "fastest" real move found. */
int max1r_vv; /* Squared speed of that move. */
double max1r_v; /* Speed of it. */
short max1v_x; /* Same as above, but for the first */
short max1v_y; /* "fastest" valid move found. */
short max1v_dx;
short max1v_dy;
int max1v_vv;
double max1v_v;
short dx_max; /* max. possible delta, */
short dy_max; /* solely based on map size. */
unsigned long max_mc; /* maximum moves count. */
short max_mc_x; /* position of the first field */
short max_mc_y; /* with max_mc moves. */
};
struct map * readmap(FILE *in, char *fname, struct map_stat *);
void freemap(struct map *);
/* Calculate all moves.
* Returns the total number of valid moves or -1 on (allocation) error.
*/
long calc_moves(struct map *);
/* Calculate the costs of every move to every finish move.
* Returns 0 on success, -1 on allocation failure.
*/
int calc_costs(struct map *);
/* Returns 1 if the given point has at least one valid move, else 0. */
int has_moves(struct map *, short, short);
/* For each start point, find a best (minimal) cost.
* Return the address of an allocated array of mv_cost_info structs,
* with all best moves per start point.
* The number of structs is written to the passed size_t pointer.
* If an error occurs, NULL is returned.
* The caller should free the the returned array after use.
*/
struct mv_cost_info *find_best_start_mvcs(struct map *, size_t *);
/* Dump all (valid) moves and the numbers of their previous moves to
* stdout.
*/
void dump_moves(struct map *);
/* Print all start points and their costs to reach a finish point. */
void dump_startcosts(struct map *);
/* For a given move, determine the next resp. previous move (depending
* on the third argument) with an additional delta delta given in
* the fourth argument. The latter must be between 0 and 8 (inclusive),
* where 0 means -1/-1, 4 means 0/0, 8 means 1/1.
* The third argument must be either 0 (determine the previous move) or
* 1 (determine the next move).
*/
struct move * adj_mv(struct map *, struct move *, int, short);
#endif