mirror of
https://github.com/libretro/mrboom-libretro.git
synced 2024-11-30 11:50:27 +00:00
Updating with new uncrustify.cfg
This commit is contained in:
parent
d35f547152
commit
3b67587df6
113
Assets/uncrustify.cfg
Normal file
113
Assets/uncrustify.cfg
Normal file
@ -0,0 +1,113 @@
|
||||
|
||||
#
|
||||
# My favorite format
|
||||
#
|
||||
|
||||
newlines = LF # AUTO (default), CRLF, CR, or LF
|
||||
|
||||
indent_with_tabs = 0 # 1=indent to level only, 2=indent with tabs
|
||||
input_tab_size = 8 # original tab size
|
||||
output_tab_size = 3 # new tab size
|
||||
indent_columns = output_tab_size
|
||||
# indent_label = 0 # pos: absolute col, neg: relative column
|
||||
indent_align_string = False # align broken strings
|
||||
indent_brace = 0
|
||||
indent_class = true
|
||||
|
||||
nl_start_of_file = remove
|
||||
# nl_start_of_file_min = 0
|
||||
nl_end_of_file = force
|
||||
nl_end_of_file_min = 1
|
||||
nl_max = 4
|
||||
nl_before_block_comment = 2
|
||||
nl_after_func_body = 2
|
||||
nl_after_func_proto_group = 2
|
||||
|
||||
nl_assign_brace = add # "= {" vs "= \n {"
|
||||
nl_enum_brace = add # "enum {" vs "enum \n {"
|
||||
nl_union_brace = add # "union {" vs "union \n {"
|
||||
nl_struct_brace = add # "struct {" vs "struct \n {"
|
||||
nl_do_brace = add # "do {" vs "do \n {"
|
||||
nl_if_brace = add # "if () {" vs "if () \n {"
|
||||
nl_for_brace = add # "for () {" vs "for () \n {"
|
||||
nl_else_brace = add # "else {" vs "else \n {"
|
||||
nl_while_brace = add # "while () {" vs "while () \n {"
|
||||
nl_switch_brace = add # "switch () {" vs "switch () \n {"
|
||||
nl_func_var_def_blk = 1
|
||||
nl_before_case = 1
|
||||
nl_fcall_brace = add # "foo() {" vs "foo()\n{"
|
||||
nl_fdef_brace = add # "int foo() {" vs "int foo()\n{"
|
||||
nl_after_return = TRUE
|
||||
nl_brace_while = remove
|
||||
nl_brace_else = add
|
||||
nl_squeeze_ifdef = TRUE
|
||||
|
||||
pos_bool = trail # BOOL ops on trailing end
|
||||
|
||||
eat_blanks_before_close_brace = TRUE
|
||||
eat_blanks_after_open_brace = TRUE
|
||||
|
||||
|
||||
mod_paren_on_return = add # "return 1;" vs "return (1);"
|
||||
mod_full_brace_if = add # "if (a) a--;" vs "if (a) { a--; }"
|
||||
mod_full_brace_for = add # "for () a--;" vs "for () { a--; }"
|
||||
mod_full_brace_do = add # "do a--; while ();" vs "do { a--; } while ();"
|
||||
mod_full_brace_while = add # "while (a) a--;" vs "while (a) { a--; }"
|
||||
|
||||
sp_before_byref = remove
|
||||
sp_before_semi = remove
|
||||
sp_paren_paren = remove # space between (( and ))
|
||||
sp_return_paren = remove # "return (1);" vs "return(1);"
|
||||
sp_sizeof_paren = remove # "sizeof (int)" vs "sizeof(int)"
|
||||
sp_before_sparen = force # "if (" vs "if("
|
||||
sp_after_sparen = force # "if () {" vs "if (){"
|
||||
sp_after_cast = remove # "(int) a" vs "(int)a"
|
||||
sp_inside_braces = force # "{ 1 }" vs "{1}"
|
||||
sp_inside_braces_struct = force # "{ 1 }" vs "{1}"
|
||||
sp_inside_braces_enum = force # "{ 1 }" vs "{1}"
|
||||
sp_inside_paren = remove
|
||||
sp_inside_fparen = remove
|
||||
sp_inside_sparen = remove
|
||||
sp_inside_square = remove
|
||||
#sp_type_func = ignore
|
||||
sp_assign = force
|
||||
sp_arith = force
|
||||
sp_bool = force
|
||||
sp_compare = force
|
||||
sp_assign = force
|
||||
sp_after_comma = force
|
||||
sp_func_def_paren = remove # "int foo (){" vs "int foo(){"
|
||||
sp_func_call_paren = remove # "foo (" vs "foo("
|
||||
sp_func_proto_paren = remove # "int foo ();" vs "int foo();"
|
||||
sp_func_class_paren = remove
|
||||
sp_before_angle = force
|
||||
sp_after_angle = force
|
||||
sp_inside_angle = remove
|
||||
sp_sparen_brace = add
|
||||
sp_fparen_brace = add
|
||||
sp_after_ptr_star = remove
|
||||
sp_before_ptr_star = force
|
||||
sp_between_ptr_star = remove
|
||||
|
||||
align_with_tabs = FALSE # use tabs to align
|
||||
align_on_tabstop = FALSE # align on tabstops
|
||||
align_enum_equ_span = 4
|
||||
align_nl_cont = TRUE
|
||||
align_var_def_span = 1
|
||||
align_var_def_thresh = 12
|
||||
align_var_def_inline = TRUE
|
||||
#align_var_def_star = TRUE
|
||||
align_var_def_colon = TRUE
|
||||
align_assign_span = 1
|
||||
align_assign_thresh = 12
|
||||
align_struct_init_span = 3
|
||||
align_var_struct_span = 99
|
||||
align_right_cmt_span = 3
|
||||
align_pp_define_span = 3
|
||||
align_pp_define_gap = 4
|
||||
align_number_right = TRUE
|
||||
align_typedef_span = 5
|
||||
align_typedef_gap = 3
|
||||
|
||||
cmt_star_cont = TRUE
|
||||
|
705
ai/Bot.cpp
705
ai/Bot.cpp
@ -4,362 +4,479 @@
|
||||
#include "GridFunctions.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#define IFTRACES ((debugTracesPlayer(_playerIndex)) && (traceMask & DEBUG_MASK_GRIDS))
|
||||
#define IFTRACES ((debugTracesPlayer(_playerIndex)) && (traceMask & DEBUG_MASK_GRIDS))
|
||||
|
||||
Bot::Bot(int playerIndex) {
|
||||
_playerIndex=playerIndex;
|
||||
initBot();
|
||||
Bot::Bot(int playerIndex)
|
||||
{
|
||||
_playerIndex = playerIndex;
|
||||
initBot();
|
||||
}
|
||||
|
||||
void Bot::initBot() {
|
||||
calculatedBestCellToDropABomb=0;
|
||||
calculatedBestCellToPickUpBonus=0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
bestExplosionsGrid[i][j]=0;
|
||||
noDangerGrid[i][j]=false;
|
||||
}
|
||||
}
|
||||
_direction1FrameAgo=button_error;
|
||||
_direction2FramesAgo=button_error;
|
||||
_shiveringCounter=0;
|
||||
void Bot::initBot()
|
||||
{
|
||||
calculatedBestCellToDropABomb = 0;
|
||||
calculatedBestCellToPickUpBonus = 0;
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
bestExplosionsGrid[i][j] = 0;
|
||||
noDangerGrid[i][j] = false;
|
||||
}
|
||||
}
|
||||
_direction1FrameAgo = button_error;
|
||||
_direction2FramesAgo = button_error;
|
||||
_shiveringCounter = 0;
|
||||
}
|
||||
|
||||
bool Bot::cellSafe(int cell) {
|
||||
int cellX=CELLX(cell);
|
||||
int cellY=CELLY(cell);
|
||||
return (!dangerGrid[cellX][cellY] && !flameGrid[cellX][cellY]);
|
||||
bool Bot::cellSafe(int cell)
|
||||
{
|
||||
int cellX = CELLX(cell);
|
||||
int cellY = CELLY(cell);
|
||||
|
||||
return(!dangerGrid[cellX][cellY] && !flameGrid[cellX][cellY]);
|
||||
}
|
||||
|
||||
int Bot::bestBonusCell() {
|
||||
if (!isAboutToWin() && travelGrid.cost(calculatedBestCellToPickUpBonus)!=TRAVELCOST_CANTGO
|
||||
&& cellSafe(calculatedBestCellToPickUpBonus))
|
||||
{
|
||||
return calculatedBestCellToPickUpBonus;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
int Bot::bestBonusCell()
|
||||
{
|
||||
if (!isAboutToWin() && travelGrid.cost(calculatedBestCellToPickUpBonus) != TRAVELCOST_CANTGO &&
|
||||
cellSafe(calculatedBestCellToPickUpBonus))
|
||||
{
|
||||
return(calculatedBestCellToPickUpBonus);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int Bot::scoreForBonus(Bonus bonus,int x,int y) {
|
||||
if (!bonusPlayerWouldLike(_playerIndex,bonus)) {
|
||||
if (((bonus==bonus_remote) || (bonus==bonus_egg) || (bonus==bonus_roller)) && (isPlayerFastestToCell(_playerIndex,x,y))) {
|
||||
if (isSameTeamTwoFastestToCell(x,y)) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("%d we are the fastest 2 to bonus %d (%d/%d) ignoring\n",_playerIndex,bonus,x,y);
|
||||
return 0;
|
||||
} else {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("%d should pick bonus %d (%d/%d) for safety reason\n",_playerIndex,bonus,x,y);
|
||||
}
|
||||
}
|
||||
}
|
||||
int distance=travelSafeGrid.cost(x,y);
|
||||
if (distance==TRAVELCOST_CANTGO) return 0;
|
||||
switch (bonus)
|
||||
{
|
||||
case bonus_push:
|
||||
case bonus_remote:
|
||||
case bonus_bulletproofjacket:
|
||||
distance/=4;
|
||||
break;
|
||||
case bonus_egg:
|
||||
case bonus_heart:
|
||||
case bonus_roller:
|
||||
distance/=8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (distance<100) {
|
||||
return (TRAVELCOST_CANTGO-distance);
|
||||
} else {
|
||||
if (isPlayerFastestToCell(_playerIndex,x,y)) {
|
||||
return (TRAVELCOST_CANTGO-distance);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
int Bot::scoreForBonus(Bonus bonus, int x, int y)
|
||||
{
|
||||
if (!bonusPlayerWouldLike(_playerIndex, bonus))
|
||||
{
|
||||
if (((bonus == bonus_remote) || (bonus == bonus_egg) || (bonus == bonus_roller)) && (isPlayerFastestToCell(_playerIndex, x, y)))
|
||||
{
|
||||
if (isSameTeamTwoFastestToCell(x, y))
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("%d we are the fastest 2 to bonus %d (%d/%d) ignoring\n", _playerIndex, bonus, x, y);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("%d should pick bonus %d (%d/%d) for safety reason\n", _playerIndex, bonus, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int distance = travelSafeGrid.cost(x, y);
|
||||
if (distance == TRAVELCOST_CANTGO)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
switch (bonus)
|
||||
{
|
||||
case bonus_push:
|
||||
case bonus_remote:
|
||||
case bonus_bulletproofjacket:
|
||||
distance /= 4;
|
||||
break;
|
||||
|
||||
case bonus_egg:
|
||||
case bonus_heart:
|
||||
case bonus_roller:
|
||||
distance /= 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (distance < 100)
|
||||
{
|
||||
return(TRAVELCOST_CANTGO - distance);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isPlayerFastestToCell(_playerIndex, x, y))
|
||||
{
|
||||
return(TRAVELCOST_CANTGO - distance);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint8_t Bot::calculateBestCellToPickUpBonus() {
|
||||
int bestCell=-1;
|
||||
int bestScore=0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
Bonus bonus=bonusInCell(i,j);
|
||||
if (bonus!=no_bonus) {
|
||||
int score=scoreForBonus(bonus,i,j);
|
||||
if (score>bestScore) {
|
||||
int cellIndex=CELLINDEX(i,j);
|
||||
bestCell=cellIndex;
|
||||
bestScore=score;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/calculateBestCellToPickUpBonus: %d/%d:bestCell=%d bestScore=%d\n",frameNumber(),_playerIndex,bestCell,bestScore);
|
||||
return bestCell;
|
||||
uint8_t Bot::calculateBestCellToPickUpBonus()
|
||||
{
|
||||
int bestCell = -1;
|
||||
int bestScore = 0;
|
||||
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
Bonus bonus = bonusInCell(i, j);
|
||||
if (bonus != no_bonus)
|
||||
{
|
||||
int score = scoreForBonus(bonus, i, j);
|
||||
if (score > bestScore)
|
||||
{
|
||||
int cellIndex = CELLINDEX(i, j);
|
||||
bestCell = cellIndex;
|
||||
bestScore = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/calculateBestCellToPickUpBonus: %d/%d:bestCell=%d bestScore=%d\n", frameNumber(), _playerIndex, bestCell, bestScore);
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
|
||||
|
||||
int noise(int player,int x,int y) {
|
||||
return (x+player+y)%nb_dyna;
|
||||
int noise(int player, int x, int y)
|
||||
{
|
||||
return((x + player + y) % nb_dyna);
|
||||
}
|
||||
|
||||
int Bot::bestCellToDropABomb()
|
||||
{
|
||||
int bestCell = -1;
|
||||
int bestScore = 0;
|
||||
|
||||
int Bot::bestCellToDropABomb() {
|
||||
int bestCell=-1;
|
||||
int bestScore=0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
int score = bestExplosionsGrid[i][j] * 128;
|
||||
if (score)
|
||||
{
|
||||
score += noise(_playerIndex, i, j);
|
||||
}
|
||||
int travelCost = 1 + travelGrid.cost(i, j) / 16;
|
||||
if (score > travelCost)
|
||||
{
|
||||
score = score / travelCost;
|
||||
}
|
||||
|
||||
int score=bestExplosionsGrid[i][j]*128;
|
||||
if (score) score+=noise(_playerIndex,i,j);
|
||||
int travelCost=1+travelGrid.cost(i,j)/16;
|
||||
if (score>travelCost) {
|
||||
score=score/travelCost;
|
||||
}
|
||||
|
||||
if (score>bestScore) {
|
||||
bestCell=CELLINDEX(i,j);
|
||||
bestScore=score;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestCell;
|
||||
if (score > bestScore)
|
||||
{
|
||||
bestCell = CELLINDEX(i, j);
|
||||
bestScore = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
|
||||
int Bot::bestSafeCell() {
|
||||
int bestCell=cellPlayer(_playerIndex);
|
||||
int bestScore=0;
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
if (!somethingThatIsNoTABombAndThatWouldStopPlayer(i,j)) {
|
||||
int score=TRAVELCOST_CANTGO-travelGrid.cost(i,j);
|
||||
if ((score>bestScore) && cellSafe(CELLINDEX(i,j))) {
|
||||
int cellIndex=CELLINDEX(i,j);
|
||||
bestCell=cellIndex;
|
||||
bestScore=score;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestCell;
|
||||
int Bot::bestSafeCell()
|
||||
{
|
||||
int bestCell = cellPlayer(_playerIndex);
|
||||
int bestScore = 0;
|
||||
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
if (!somethingThatIsNoTABombAndThatWouldStopPlayer(i, j))
|
||||
{
|
||||
int score = TRAVELCOST_CANTGO - travelGrid.cost(i, j);
|
||||
if ((score > bestScore) && cellSafe(CELLINDEX(i, j)))
|
||||
{
|
||||
int cellIndex = CELLINDEX(i, j);
|
||||
bestCell = cellIndex;
|
||||
bestScore = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
|
||||
|
||||
|
||||
bool Bot::isSomewhatInTheMiddleOfCell() {
|
||||
int x=GETXPIXELSTOCENTEROFCELL(_playerIndex);
|
||||
int y=GETYPIXELSTOCENTEROFCELL(_playerIndex);
|
||||
return ((x>-MAX_PIXELS_PER_FRAME/2) && (x<MAX_PIXELS_PER_FRAME/2) && (y<MAX_PIXELS_PER_FRAME/2) && (y>-MAX_PIXELS_PER_FRAME/2));
|
||||
bool Bot::isSomewhatInTheMiddleOfCell()
|
||||
{
|
||||
int x = GETXPIXELSTOCENTEROFCELL(_playerIndex);
|
||||
int y = GETYPIXELSTOCENTEROFCELL(_playerIndex);
|
||||
|
||||
return((x > -MAX_PIXELS_PER_FRAME / 2) && (x < MAX_PIXELS_PER_FRAME / 2) && (y < MAX_PIXELS_PER_FRAME / 2) && (y > -MAX_PIXELS_PER_FRAME / 2));
|
||||
}
|
||||
|
||||
bool Bot::amISafe() {
|
||||
return cellSafe(cellPlayer(_playerIndex));
|
||||
bool Bot::amISafe()
|
||||
{
|
||||
return(cellSafe(cellPlayer(_playerIndex)));
|
||||
}
|
||||
|
||||
bool Bot::isThereABombUnderMe() {
|
||||
int x=xPlayer(_playerIndex);
|
||||
int y=yPlayer(_playerIndex);
|
||||
return bombInCell(x,y);
|
||||
bool Bot::isThereABombUnderMe()
|
||||
{
|
||||
int x = xPlayer(_playerIndex);
|
||||
int y = yPlayer(_playerIndex);
|
||||
|
||||
return(bombInCell(x, y));
|
||||
}
|
||||
|
||||
int Bot::howManyBombsLeft() {
|
||||
return nbBombsLeft(_playerIndex);
|
||||
int Bot::howManyBombsLeft()
|
||||
{
|
||||
return(nbBombsLeft(_playerIndex));
|
||||
}
|
||||
|
||||
void Bot::printGrid()
|
||||
{
|
||||
if (IFTRACES) {
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
db brickKind=m.truc[i+j*grid_size_x_with_padding];
|
||||
if (monsterInCell(i,j) || playerInCell(i,j)) {
|
||||
if (monsterInCell(i,j)) {
|
||||
log_debug(" 8( ");
|
||||
} else {
|
||||
log_debug(" 8) ");
|
||||
}
|
||||
} else {
|
||||
switch (brickKind) {
|
||||
case 1:
|
||||
log_debug("[======]");
|
||||
break;
|
||||
case 2:
|
||||
log_debug("(******)");
|
||||
break;
|
||||
default:
|
||||
if (no_bonus!=bonusInCell(i,j)) {
|
||||
log_debug(" (%d) ",bonusInCell(i,j));
|
||||
} else {
|
||||
log_debug(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
log_debug("\n");
|
||||
}
|
||||
log_debug("bestExplosionsGrid player %d\n",_playerIndex);
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
log_debug("%04d",bestExplosionsGrid[i][j]);
|
||||
if (dangerGrid[i][j]) {
|
||||
log_debug("x");
|
||||
} else {
|
||||
log_debug("_");
|
||||
}
|
||||
}
|
||||
log_debug("\n");
|
||||
}
|
||||
log_debug("travelCostGrid %d/%d cell:%d x:%d y:%d adderX=%d adderY=%d\n",frameNumber(),_playerIndex,cellPlayer(_playerIndex), xPlayer(_playerIndex),yPlayer(_playerIndex),GETXPIXELSTOCENTEROFCELL(_playerIndex)*framesToCrossACell(_playerIndex)/CELLPIXELSSIZE,
|
||||
GETYPIXELSTOCENTEROFCELL(_playerIndex)*framesToCrossACell(_playerIndex)/CELLPIXELSSIZE);
|
||||
travelGrid.print();
|
||||
if (IFTRACES)
|
||||
{
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
db brickKind = m.truc[i + j * grid_size_x_with_padding];
|
||||
if (monsterInCell(i, j) || playerInCell(i, j))
|
||||
{
|
||||
if (monsterInCell(i, j))
|
||||
{
|
||||
log_debug(" 8( ");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug(" 8) ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (brickKind)
|
||||
{
|
||||
case 1:
|
||||
log_debug("[======]");
|
||||
break;
|
||||
|
||||
log_debug("travelCostSafeGrid\n");
|
||||
travelSafeGrid.print();
|
||||
case 2:
|
||||
log_debug("(******)");
|
||||
break;
|
||||
|
||||
log_debug("%d flameGrid player %d\n",m.changement,_playerIndex);
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
log_debug("%04d ",flameGrid[i][j]);
|
||||
}
|
||||
log_debug("\n");
|
||||
}
|
||||
log_debug("hasRemote=%d isCellCulDeSac=%d flamesize:%d lapipipino:%d lapipipino5:%d amISafe=%d\n",hasRemote(_playerIndex),isCellCulDeSac(xPlayer(_playerIndex),yPlayer(_playerIndex)),flameSize(_playerIndex),m.lapipipino[_playerIndex],m.lapipipino5[_playerIndex],amISafe());
|
||||
}
|
||||
default:
|
||||
if (no_bonus != bonusInCell(i, j))
|
||||
{
|
||||
log_debug(" (%d) ", bonusInCell(i, j));
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
log_debug("\n");
|
||||
}
|
||||
log_debug("bestExplosionsGrid player %d\n", _playerIndex);
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
log_debug("%04d", bestExplosionsGrid[i][j]);
|
||||
if (dangerGrid[i][j])
|
||||
{
|
||||
log_debug("x");
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("_");
|
||||
}
|
||||
}
|
||||
log_debug("\n");
|
||||
}
|
||||
log_debug("travelCostGrid %d/%d cell:%d x:%d y:%d adderX=%d adderY=%d\n", frameNumber(), _playerIndex, cellPlayer(_playerIndex), xPlayer(_playerIndex), yPlayer(_playerIndex), GETXPIXELSTOCENTEROFCELL(_playerIndex) * framesToCrossACell(_playerIndex) / CELLPIXELSSIZE,
|
||||
GETYPIXELSTOCENTEROFCELL(_playerIndex) * framesToCrossACell(_playerIndex) / CELLPIXELSSIZE);
|
||||
travelGrid.print();
|
||||
|
||||
log_debug("travelCostSafeGrid\n");
|
||||
travelSafeGrid.print();
|
||||
|
||||
log_debug("%d flameGrid player %d\n", m.changement, _playerIndex);
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
log_debug("%04d ", flameGrid[i][j]);
|
||||
}
|
||||
log_debug("\n");
|
||||
}
|
||||
log_debug("hasRemote=%d isCellCulDeSac=%d flamesize:%d lapipipino:%d lapipipino5:%d amISafe=%d\n", hasRemote(_playerIndex), isCellCulDeSac(xPlayer(_playerIndex), yPlayer(_playerIndex)), flameSize(_playerIndex), m.lapipipino[_playerIndex], m.lapipipino5[_playerIndex], amISafe());
|
||||
}
|
||||
}
|
||||
|
||||
void Bot::stopWalking() {
|
||||
mrboom_update_input(button_up,_playerIndex,0,true);
|
||||
mrboom_update_input(button_down,_playerIndex,0,true);
|
||||
mrboom_update_input(button_left,_playerIndex,0,true);
|
||||
mrboom_update_input(button_right,_playerIndex,0,true);
|
||||
void Bot::stopWalking()
|
||||
{
|
||||
mrboom_update_input(button_up, _playerIndex, 0, true);
|
||||
mrboom_update_input(button_down, _playerIndex, 0, true);
|
||||
mrboom_update_input(button_left, _playerIndex, 0, true);
|
||||
mrboom_update_input(button_right, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
void Bot::startPushingRemoteButton() {
|
||||
mrboom_update_input(button_a,_playerIndex,1,true);
|
||||
void Bot::startPushingRemoteButton()
|
||||
{
|
||||
mrboom_update_input(button_a, _playerIndex, 1, true);
|
||||
}
|
||||
|
||||
void Bot::stopPushingRemoteButton() {
|
||||
mrboom_update_input(button_a,_playerIndex,0,true);
|
||||
void Bot::stopPushingRemoteButton()
|
||||
{
|
||||
mrboom_update_input(button_a, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
void Bot::startPushingJumpButton() {
|
||||
mrboom_update_input(button_x,_playerIndex,1,true);
|
||||
void Bot::startPushingJumpButton()
|
||||
{
|
||||
mrboom_update_input(button_x, _playerIndex, 1, true);
|
||||
}
|
||||
|
||||
void Bot::stopPushingJumpButton() {
|
||||
mrboom_update_input(button_x,_playerIndex,0,true);
|
||||
void Bot::stopPushingJumpButton()
|
||||
{
|
||||
mrboom_update_input(button_x, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
void Bot::startPushingBombDropButton() {
|
||||
pushingDropBombButton=true;
|
||||
mrboom_update_input(button_b,_playerIndex,1,true);
|
||||
void Bot::startPushingBombDropButton()
|
||||
{
|
||||
pushingDropBombButton = true;
|
||||
mrboom_update_input(button_b, _playerIndex, 1, true);
|
||||
}
|
||||
|
||||
void Bot::stopPushingBombDropButton() {
|
||||
pushingDropBombButton=false;
|
||||
mrboom_update_input(button_b,_playerIndex,0,true);
|
||||
void Bot::stopPushingBombDropButton()
|
||||
{
|
||||
pushingDropBombButton = false;
|
||||
mrboom_update_input(button_b, _playerIndex, 0, true);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int howToGoDebug;
|
||||
#endif
|
||||
bool Bot::walkToCell(int cell) {
|
||||
#ifdef DEBUG
|
||||
howToGoDebug=0;
|
||||
#endif
|
||||
bool shouldJump=false;
|
||||
enum Button direction = howToGo(_playerIndex,CELLX(cell), CELLY(cell), travelSafeGrid, shouldJump);
|
||||
if (direction==button_error) {
|
||||
direction = howToGo(_playerIndex,CELLX(cell), CELLY(cell), travelGrid, shouldJump);
|
||||
}
|
||||
bool Bot::walkToCell(int cell)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
howToGoDebug = 0;
|
||||
#endif
|
||||
bool shouldJump = false;
|
||||
enum Button direction = howToGo(_playerIndex, CELLX(cell), CELLY(cell), travelSafeGrid, shouldJump);
|
||||
if (direction == button_error)
|
||||
{
|
||||
direction = howToGo(_playerIndex, CELLX(cell), CELLY(cell), travelGrid, shouldJump);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
walkingToCell[_playerIndex]=cell;
|
||||
if (tracesDecisions(_playerIndex)) {
|
||||
char * directionText=(char *)"?";
|
||||
switch (direction) {
|
||||
case button_up:
|
||||
directionText=(char *)"button_up";
|
||||
break;
|
||||
case button_down:
|
||||
directionText=(char *)"button_down";
|
||||
break;
|
||||
case button_left:
|
||||
directionText=(char *)"button_left";
|
||||
break;
|
||||
case button_right:
|
||||
directionText=(char *)"button_right";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
log_debug("\nBOTTREEDECISIONS: %d/%d:howToGo to %d:%s %d/%d shouldjump=%d\n",frameNumber(),_playerIndex,cell,directionText,GETXPIXELSTOCENTEROFCELL(_playerIndex),GETYPIXELSTOCENTEROFCELL(_playerIndex),shouldJump);
|
||||
}
|
||||
#endif
|
||||
stopWalking();
|
||||
#ifdef DEBUG
|
||||
walkingToCell[_playerIndex] = cell;
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
char *directionText = (char *)"?";
|
||||
switch (direction)
|
||||
{
|
||||
case button_up:
|
||||
directionText = (char *)"button_up";
|
||||
break;
|
||||
|
||||
if (shouldJump) {
|
||||
startPushingJumpButton();
|
||||
}
|
||||
case button_down:
|
||||
directionText = (char *)"button_down";
|
||||
break;
|
||||
|
||||
if (hasInvertedDisease(_playerIndex)) {
|
||||
switch (direction) {
|
||||
case button_up:
|
||||
direction=button_down;
|
||||
break;
|
||||
case button_down:
|
||||
direction=button_up;
|
||||
break;
|
||||
case button_left:
|
||||
direction=button_right;
|
||||
break;
|
||||
case button_right:
|
||||
direction=button_left;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
case button_left:
|
||||
directionText = (char *)"button_left";
|
||||
break;
|
||||
|
||||
mrboom_update_input(direction,_playerIndex,1,true);
|
||||
case button_right:
|
||||
directionText = (char *)"button_right";
|
||||
break;
|
||||
|
||||
#define MAX_SHIVERING 3
|
||||
if ((_direction2FramesAgo==direction) && (_direction1FrameAgo!=direction)) {
|
||||
_shiveringCounter++;
|
||||
if (_shiveringCounter>=MAX_SHIVERING) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingBombDropButton\n",frameNumber(),_playerIndex);
|
||||
startPushingBombDropButton();
|
||||
}
|
||||
if (_shiveringCounter>=MAX_SHIVERING*2) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingJumpButton\n",frameNumber(),_playerIndex);
|
||||
startPushingJumpButton();
|
||||
}
|
||||
if (_shiveringCounter>=MAX_SHIVERING*3) {
|
||||
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingRemoteButton\n",frameNumber(),_playerIndex);
|
||||
startPushingRemoteButton();
|
||||
}
|
||||
} else {
|
||||
_shiveringCounter=0;
|
||||
}
|
||||
_direction2FramesAgo=_direction1FrameAgo;
|
||||
_direction1FrameAgo=direction;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
log_debug("\nBOTTREEDECISIONS: %d/%d:howToGo to %d:%s %d/%d shouldjump=%d\n", frameNumber(), _playerIndex, cell, directionText, GETXPIXELSTOCENTEROFCELL(_playerIndex), GETYPIXELSTOCENTEROFCELL(_playerIndex), shouldJump);
|
||||
}
|
||||
#endif
|
||||
stopWalking();
|
||||
|
||||
return (direction!=button_error);
|
||||
if (shouldJump)
|
||||
{
|
||||
startPushingJumpButton();
|
||||
}
|
||||
|
||||
if (hasInvertedDisease(_playerIndex))
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case button_up:
|
||||
direction = button_down;
|
||||
break;
|
||||
|
||||
case button_down:
|
||||
direction = button_up;
|
||||
break;
|
||||
|
||||
case button_left:
|
||||
direction = button_right;
|
||||
break;
|
||||
|
||||
case button_right:
|
||||
direction = button_left;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mrboom_update_input(direction, _playerIndex, 1, true);
|
||||
|
||||
#define MAX_SHIVERING 3
|
||||
if ((_direction2FramesAgo == direction) && (_direction1FrameAgo != direction))
|
||||
{
|
||||
_shiveringCounter++;
|
||||
if (_shiveringCounter >= MAX_SHIVERING)
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingBombDropButton\n", frameNumber(), _playerIndex);
|
||||
}
|
||||
startPushingBombDropButton();
|
||||
}
|
||||
if (_shiveringCounter >= MAX_SHIVERING * 2)
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingJumpButton\n", frameNumber(), _playerIndex);
|
||||
}
|
||||
startPushingJumpButton();
|
||||
}
|
||||
if (_shiveringCounter >= MAX_SHIVERING * 3)
|
||||
{
|
||||
if (tracesDecisions(_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingRemoteButton\n", frameNumber(), _playerIndex);
|
||||
}
|
||||
startPushingRemoteButton();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_shiveringCounter = 0;
|
||||
}
|
||||
_direction2FramesAgo = _direction1FrameAgo;
|
||||
_direction1FrameAgo = direction;
|
||||
|
||||
return(direction != button_error);
|
||||
}
|
||||
|
||||
int Bot::getCurrentCell() {
|
||||
int x=xPlayer(_playerIndex);
|
||||
int y=yPlayer(_playerIndex);
|
||||
return CELLINDEX(x,y);
|
||||
int Bot::getCurrentCell()
|
||||
{
|
||||
int x = xPlayer(_playerIndex);
|
||||
int y = yPlayer(_playerIndex);
|
||||
|
||||
return(CELLINDEX(x, y));
|
||||
}
|
||||
|
||||
void Bot::printCellInfo(int cell) {
|
||||
log_debug("printCellInfoBot Cell:%d Bot:%d: travelCostGrid=%d bestExplosionsGrid=%d flameGrid=%d dangerGrid=%d\n", cell,_playerIndex,travelGrid.cost(cell),bestExplosionsGrid[CELLX(cell)][CELLY(cell)],flameGrid[CELLX(cell)][CELLY(cell)],dangerGrid[CELLX(cell)][CELLY(cell)]);
|
||||
void Bot::printCellInfo(int cell)
|
||||
{
|
||||
log_debug("printCellInfoBot Cell:%d Bot:%d: travelCostGrid=%d bestExplosionsGrid=%d flameGrid=%d dangerGrid=%d\n", cell, _playerIndex, travelGrid.cost(cell), bestExplosionsGrid[CELLX(cell)][CELLY(cell)], flameGrid[CELLX(cell)][CELLY(cell)], dangerGrid[CELLX(cell)][CELLY(cell)]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
75
ai/Bot.hpp
75
ai/Bot.hpp
@ -5,42 +5,43 @@
|
||||
|
||||
class Bot {
|
||||
public:
|
||||
Bot(int playerIndex);
|
||||
void initBot();
|
||||
int bestBonusCell();
|
||||
int bestCellToDropABomb();
|
||||
int bestSafeCell();
|
||||
bool isSomewhatInTheMiddleOfCell();
|
||||
bool isThereABombUnderMe();
|
||||
void stopWalking();
|
||||
void startPushingBombDropButton();
|
||||
void startPushingRemoteButton();
|
||||
void startPushingJumpButton();
|
||||
void stopPushingBombDropButton();
|
||||
void stopPushingRemoteButton();
|
||||
void stopPushingJumpButton();
|
||||
bool walkToCell(int cell);
|
||||
bool amISafe();
|
||||
int getCurrentCell();
|
||||
void printGrid();
|
||||
void printCellInfo(int cell);
|
||||
int howManyBombsLeft();
|
||||
uint8_t calculateBestCellToPickUpBonus();
|
||||
bool cellSafe(int cell);
|
||||
int scoreForBonus(Bonus bonus,int x,int y);
|
||||
int _playerIndex;
|
||||
uint8_t _direction1FrameAgo;
|
||||
uint8_t _direction2FramesAgo;
|
||||
uint8_t _shiveringCounter;
|
||||
Bot(int playerIndex);
|
||||
void initBot();
|
||||
int bestBonusCell();
|
||||
int bestCellToDropABomb();
|
||||
int bestSafeCell();
|
||||
bool isSomewhatInTheMiddleOfCell();
|
||||
bool isThereABombUnderMe();
|
||||
void stopWalking();
|
||||
void startPushingBombDropButton();
|
||||
void startPushingRemoteButton();
|
||||
void startPushingJumpButton();
|
||||
void stopPushingBombDropButton();
|
||||
void stopPushingRemoteButton();
|
||||
void stopPushingJumpButton();
|
||||
bool walkToCell(int cell);
|
||||
bool amISafe();
|
||||
int getCurrentCell();
|
||||
void printGrid();
|
||||
void printCellInfo(int cell);
|
||||
int howManyBombsLeft();
|
||||
uint8_t calculateBestCellToPickUpBonus();
|
||||
bool cellSafe(int cell);
|
||||
int scoreForBonus(Bonus bonus, int x, int y);
|
||||
|
||||
int _playerIndex;
|
||||
uint8_t _direction1FrameAgo;
|
||||
uint8_t _direction2FramesAgo;
|
||||
uint8_t _shiveringCounter;
|
||||
public:
|
||||
travelCostGrid travelGrid; // travelGrid that can cross cells set to true in DangerGrid
|
||||
travelCostGrid travelSafeGrid; // travelGrid avoiding cells set to true in DangerGrid
|
||||
uint32_t bestExplosionsGrid[grid_size_x][grid_size_y]; // score based on the nb of bricks one of my bomb there would break or of the proximity from a monster
|
||||
uint8_t calculatedBestCellToPickUpBonus;
|
||||
uint8_t calculatedBestCellToDropABomb;
|
||||
uint32_t flameGrid[grid_size_x][grid_size_y]; // 0: no flame, 1..FLAME_DURATION+1: time with a flame, FLAME_DURATION+2: time before end of flame
|
||||
bool dangerGrid[grid_size_x][grid_size_y]; // used to track all dangers, including the ones we don't know the timing: true means a flame is coming (possibily under a remote controled bomb...), or that a monster is there
|
||||
bool noDangerGrid[grid_size_x][grid_size_y]; // set to false for each cells at init, used as an empty dangerGrid instance.
|
||||
bool monsterIsComingGrid[NUMBER_OF_CELLS];
|
||||
bool pushingDropBombButton;
|
||||
travelCostGrid travelGrid; // travelGrid that can cross cells set to true in DangerGrid
|
||||
travelCostGrid travelSafeGrid; // travelGrid avoiding cells set to true in DangerGrid
|
||||
uint32_t bestExplosionsGrid[grid_size_x][grid_size_y]; // score based on the nb of bricks one of my bomb there would break or of the proximity from a monster
|
||||
uint8_t calculatedBestCellToPickUpBonus;
|
||||
uint8_t calculatedBestCellToDropABomb;
|
||||
uint32_t flameGrid[grid_size_x][grid_size_y]; // 0: no flame, 1..FLAME_DURATION+1: time with a flame, FLAME_DURATION+2: time before end of flame
|
||||
bool dangerGrid[grid_size_x][grid_size_y]; // used to track all dangers, including the ones we don't know the timing: true means a flame is coming (possibily under a remote controled bomb...), or that a monster is there
|
||||
bool noDangerGrid[grid_size_x][grid_size_y]; // set to false for each cells at init, used as an empty dangerGrid instance.
|
||||
bool monsterIsComingGrid[NUMBER_OF_CELLS];
|
||||
bool pushingDropBombButton;
|
||||
};
|
||||
|
387
ai/BotTree.cpp
387
ai/BotTree.cpp
@ -3,235 +3,302 @@
|
||||
#include "BotTree.hpp"
|
||||
|
||||
#ifdef IOS
|
||||
void std::__throw_out_of_range(char const*) {
|
||||
void std::__throw_out_of_range(char const *)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
class ConditionNode : public bt::Node
|
||||
{
|
||||
public:
|
||||
ConditionNode(Bot * bot) : Node(), bot(bot) {
|
||||
}
|
||||
void Initialize() {
|
||||
}
|
||||
virtual bool Condition() = 0;
|
||||
bt::Status Update()
|
||||
{
|
||||
if (Condition())
|
||||
return bt::Success;
|
||||
return bt::Failure;
|
||||
}
|
||||
ConditionNode(Bot *bot) : Node(), bot(bot)
|
||||
{
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Condition() = 0;
|
||||
|
||||
bt::Status Update()
|
||||
{
|
||||
if (Condition())
|
||||
{
|
||||
return(bt::Success);
|
||||
}
|
||||
return(bt::Failure);
|
||||
}
|
||||
|
||||
protected:
|
||||
Bot * bot;
|
||||
Bot *bot;
|
||||
};
|
||||
|
||||
class MoveToNode : public bt::Node
|
||||
{
|
||||
public:
|
||||
MoveToNode(Bot * bot) : Node(), bot(bot) {
|
||||
}
|
||||
void Initialize() {
|
||||
}
|
||||
virtual int Cell() = 0;
|
||||
bt::Status Update()
|
||||
{
|
||||
int cell=Cell();
|
||||
if (cell==-1) {
|
||||
if (isInMiddleOfCell(bot->_playerIndex)) {
|
||||
bot->stopWalking();
|
||||
}
|
||||
return bt::Failure;
|
||||
}
|
||||
MoveToNode(Bot *bot) : Node(), bot(bot)
|
||||
{
|
||||
}
|
||||
|
||||
if (((!(isInMiddleOfCell(bot->_playerIndex) && bot->getCurrentCell()==cell))) || (bot->getCurrentCell()!=cell))
|
||||
{
|
||||
if (bot->walkToCell(cell))
|
||||
return bt::Running;
|
||||
void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
virtual int Cell() = 0;
|
||||
|
||||
bt::Status Update()
|
||||
{
|
||||
int cell = Cell();
|
||||
|
||||
if (cell == -1)
|
||||
{
|
||||
if (isInMiddleOfCell(bot->_playerIndex))
|
||||
{
|
||||
bot->stopWalking();
|
||||
}
|
||||
return(bt::Failure);
|
||||
}
|
||||
|
||||
if (((!(isInMiddleOfCell(bot->_playerIndex) && bot->getCurrentCell() == cell))) || (bot->getCurrentCell() != cell))
|
||||
{
|
||||
if (bot->walkToCell(cell))
|
||||
{
|
||||
return(bt::Running);
|
||||
}
|
||||
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:Failed to go to %d (%d/%d)\n", frameNumber(), bot->_playerIndex, cell, CELLX(cell), CELLY(cell));
|
||||
}
|
||||
return(bt::Failure);
|
||||
}
|
||||
bot->stopWalking();
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:stopWalking arrived in %d (%d/%d)\n", frameNumber(), bot->_playerIndex, cell, CELLX(cell), CELLY(cell));
|
||||
}
|
||||
return(bt::Success);
|
||||
}
|
||||
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:Failed to go to %d (%d/%d)\n",frameNumber(),bot->_playerIndex,cell,CELLX(cell),CELLY(cell));
|
||||
return bt::Failure;
|
||||
}
|
||||
bot->stopWalking();
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:stopWalking arrived in %d (%d/%d)\n",frameNumber(),bot->_playerIndex,cell,CELLX(cell),CELLY(cell));
|
||||
return bt::Success;
|
||||
}
|
||||
protected:
|
||||
Bot * bot;
|
||||
Bot *bot;
|
||||
};
|
||||
|
||||
class MoveToBonus : public MoveToNode
|
||||
{
|
||||
public:
|
||||
MoveToBonus(Bot * bot) : MoveToNode(bot) {
|
||||
}
|
||||
int Cell() {
|
||||
int bestCell=bot->bestBonusCell();
|
||||
MoveToBonus(Bot *bot) : MoveToNode(bot)
|
||||
{
|
||||
}
|
||||
|
||||
int Cell()
|
||||
{
|
||||
int bestCell = bot->bestBonusCell();
|
||||
|
||||
#ifdef DEBUG
|
||||
botStates[bot->_playerIndex]=goingBonus;
|
||||
botStates[bot->_playerIndex] = goingBonus;
|
||||
#endif
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBonus:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
|
||||
return bestCell;
|
||||
}
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:gotoBonus:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
};
|
||||
|
||||
class MoveToBombBestBombCell : public MoveToNode
|
||||
{
|
||||
public:
|
||||
MoveToBombBestBombCell(Bot * bot) : MoveToNode(bot) {
|
||||
}
|
||||
int Cell() {
|
||||
int bestCell=bot->bestCellToDropABomb();
|
||||
MoveToBombBestBombCell(Bot *bot) : MoveToNode(bot)
|
||||
{
|
||||
}
|
||||
|
||||
int Cell()
|
||||
{
|
||||
int bestCell = bot->bestCellToDropABomb();
|
||||
|
||||
#ifdef DEBUG
|
||||
botStates[bot->_playerIndex]=goingBomb;
|
||||
botStates[bot->_playerIndex] = goingBomb;
|
||||
#endif
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBestBombCell:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
|
||||
return bestCell;
|
||||
}
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:gotoBestBombCell:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
};
|
||||
|
||||
class MoveToSafeCell : public MoveToNode
|
||||
{
|
||||
public:
|
||||
MoveToSafeCell(Bot * bot) : MoveToNode(bot) {
|
||||
}
|
||||
int Cell() {
|
||||
int bestCell=bot->bestSafeCell();
|
||||
MoveToSafeCell(Bot *bot) : MoveToNode(bot)
|
||||
{
|
||||
}
|
||||
|
||||
int Cell()
|
||||
{
|
||||
int bestCell = bot->bestSafeCell();
|
||||
|
||||
#ifdef DEBUG
|
||||
botStates[bot->_playerIndex]=goingSafe;
|
||||
botStates[bot->_playerIndex] = goingSafe;
|
||||
#endif
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBestSafeCell:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
|
||||
return bestCell;
|
||||
}
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:gotoBestSafeCell:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
|
||||
}
|
||||
return(bestCell);
|
||||
}
|
||||
};
|
||||
|
||||
class ConditionBombsLeft : public ConditionNode
|
||||
{
|
||||
public:
|
||||
ConditionBombsLeft(Bot * bot) : ConditionNode(bot) {
|
||||
}
|
||||
bool Condition() {
|
||||
// condition "i have more bombs"
|
||||
int howManyBombs=bot->howManyBombsLeft();
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:bombLeft:%d\n",frameNumber(),bot->_playerIndex,howManyBombs);
|
||||
return (howManyBombs);
|
||||
}
|
||||
ConditionBombsLeft(Bot *bot) : ConditionNode(bot)
|
||||
{
|
||||
}
|
||||
|
||||
bool Condition()
|
||||
{
|
||||
// condition "i have more bombs"
|
||||
int howManyBombs = bot->howManyBombsLeft();
|
||||
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:bombLeft:%d\n", frameNumber(), bot->_playerIndex, howManyBombs);
|
||||
}
|
||||
return(howManyBombs);
|
||||
}
|
||||
};
|
||||
|
||||
class ConditionDropBomb : public ConditionNode
|
||||
{
|
||||
public:
|
||||
ConditionDropBomb(Bot * bot) : ConditionNode(bot) {
|
||||
}
|
||||
bool Condition() {
|
||||
bot->startPushingBombDropButton(); //TOFIX ? return false or running ?
|
||||
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:dropBomb\n",frameNumber(),bot->_playerIndex);
|
||||
return true;
|
||||
}
|
||||
ConditionDropBomb(Bot *bot) : ConditionNode(bot)
|
||||
{
|
||||
}
|
||||
|
||||
bool Condition()
|
||||
{
|
||||
bot->startPushingBombDropButton(); //TOFIX ? return false or running ?
|
||||
if (tracesDecisions(bot->_playerIndex))
|
||||
{
|
||||
log_debug("BOTTREEDECISIONS: %d/%d:dropBomb\n", frameNumber(), bot->_playerIndex);
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
};
|
||||
|
||||
BotTree::BotTree(int playerIndex) : Bot(playerIndex)
|
||||
{
|
||||
tree = new bt::BehaviorTree();
|
||||
tree = new bt::BehaviorTree();
|
||||
|
||||
MoveToBonus * gotoBonus = new MoveToBonus(this);
|
||||
bt::Sequence * bombSeq = new bt::Sequence();
|
||||
MoveToBonus * gotoBonus = new MoveToBonus(this);
|
||||
bt::Sequence *bombSeq = new bt::Sequence();
|
||||
|
||||
ConditionBombsLeft * bombLeft = new ConditionBombsLeft(this);
|
||||
bombSeq->AddChild(bombLeft);
|
||||
ConditionBombsLeft *bombLeft = new ConditionBombsLeft(this);
|
||||
bombSeq->AddChild(bombLeft);
|
||||
|
||||
MoveToBombBestBombCell * gotoBestBombCell = new MoveToBombBestBombCell(this);
|
||||
bombSeq->AddChild(gotoBestBombCell);
|
||||
MoveToBombBestBombCell *gotoBestBombCell = new MoveToBombBestBombCell(this);
|
||||
bombSeq->AddChild(gotoBestBombCell);
|
||||
|
||||
ConditionDropBomb * dropBomb = new ConditionDropBomb(this);
|
||||
bombSeq->AddChild(dropBomb);
|
||||
ConditionDropBomb *dropBomb = new ConditionDropBomb(this);
|
||||
bombSeq->AddChild(dropBomb);
|
||||
|
||||
MoveToSafeCell * gotoSafePlace = new MoveToSafeCell(this);
|
||||
bt::Selector * rootNode = new bt::Selector();
|
||||
rootNode->AddChild(gotoBonus);
|
||||
rootNode->AddChild(bombSeq);
|
||||
rootNode->AddChild(gotoSafePlace);
|
||||
tree->SetRoot(rootNode);
|
||||
MoveToSafeCell *gotoSafePlace = new MoveToSafeCell(this);
|
||||
bt::Selector * rootNode = new bt::Selector();
|
||||
rootNode->AddChild(gotoBonus);
|
||||
rootNode->AddChild(bombSeq);
|
||||
rootNode->AddChild(gotoSafePlace);
|
||||
tree->SetRoot(rootNode);
|
||||
}
|
||||
|
||||
void BotTree::updateGrids()
|
||||
{
|
||||
updateFlameAndDangerGridsWithBombs(_playerIndex,flameGrid,dangerGrid);
|
||||
updateDangerGridWithMonstersSickPlayersAndCulDeSacs(_playerIndex,dangerGrid);
|
||||
updateDangerGridWithMonster4CellsTerritories(dangerGrid);
|
||||
updateMonsterIsComingGrid(monsterIsComingGrid);
|
||||
updateTravelGrid(_playerIndex,false,travelGrid,flameGrid,noDangerGrid);
|
||||
updateTravelGrid(_playerIndex,false,travelSafeGrid,flameGrid,dangerGrid);
|
||||
updateFlameAndDangerGridsWithBombs(_playerIndex, flameGrid, dangerGrid);
|
||||
updateDangerGridWithMonstersSickPlayersAndCulDeSacs(_playerIndex, dangerGrid);
|
||||
updateDangerGridWithMonster4CellsTerritories(dangerGrid);
|
||||
updateMonsterIsComingGrid(monsterIsComingGrid);
|
||||
updateTravelGrid(_playerIndex, false, travelGrid, flameGrid, noDangerGrid);
|
||||
updateTravelGrid(_playerIndex, false, travelSafeGrid, flameGrid, dangerGrid);
|
||||
|
||||
#ifdef DEBUG
|
||||
printGrid();
|
||||
printGrid();
|
||||
#endif
|
||||
if (!((frameNumber()+_playerIndex)%nb_dyna))
|
||||
{
|
||||
calculatedBestCellToPickUpBonus=calculateBestCellToPickUpBonus();
|
||||
}
|
||||
updateBestExplosionGrid(_playerIndex,bestExplosionsGrid,travelGrid,flameGrid,dangerGrid);
|
||||
if (!((frameNumber() + _playerIndex) % nb_dyna))
|
||||
{
|
||||
calculatedBestCellToPickUpBonus = calculateBestCellToPickUpBonus();
|
||||
}
|
||||
updateBestExplosionGrid(_playerIndex, bestExplosionsGrid, travelGrid, flameGrid, dangerGrid);
|
||||
}
|
||||
|
||||
|
||||
void BotTree::tick() {
|
||||
stopPushingRemoteButton();
|
||||
stopPushingBombDropButton();
|
||||
stopPushingJumpButton();
|
||||
tree->Update();
|
||||
if (monsterIsComingGrid[cellPlayer(_playerIndex)]) {
|
||||
startPushingBombDropButton();
|
||||
}
|
||||
if (isSomewhatInTheMiddleOfCell() && frameNumber()%2 && pushingDropBombButton==false) {
|
||||
bool cantPlaceMoreBombsAndSafe=(((bestCellToDropABomb()==-1) || (howManyBombsLeft()==0)) && amISafe());
|
||||
if (cantPlaceMoreBombsAndSafe || shouldActivateRemote(_playerIndex)) {
|
||||
startPushingRemoteButton();
|
||||
}
|
||||
}
|
||||
void BotTree::tick()
|
||||
{
|
||||
stopPushingRemoteButton();
|
||||
stopPushingBombDropButton();
|
||||
stopPushingJumpButton();
|
||||
tree->Update();
|
||||
if (monsterIsComingGrid[cellPlayer(_playerIndex)])
|
||||
{
|
||||
startPushingBombDropButton();
|
||||
}
|
||||
if (isSomewhatInTheMiddleOfCell() && frameNumber() % 2 && pushingDropBombButton == false)
|
||||
{
|
||||
bool cantPlaceMoreBombsAndSafe = (((bestCellToDropABomb() == -1) || (howManyBombsLeft() == 0)) && amISafe());
|
||||
if (cantPlaceMoreBombsAndSafe || shouldActivateRemote(_playerIndex))
|
||||
{
|
||||
startPushingRemoteButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// filled by serialize...
|
||||
static size_t serializeSize=0;
|
||||
static size_t serializeSize = 0;
|
||||
|
||||
size_t BotTree::serialize_size(void) {
|
||||
if(serializeSize==0) {
|
||||
uint8_t tmpBuffer[MEM_STREAM_BUFFER_SIZE];
|
||||
serialize(tmpBuffer);
|
||||
log_error("HARDCODED_RETRO_SERIALIZE_SIZE=SIZE_SER+%d*8\n",serializeSize);
|
||||
}
|
||||
assert(serializeSize!=0);
|
||||
return serializeSize;
|
||||
}
|
||||
bool BotTree::serialize(void *data_) {
|
||||
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
|
||||
static memstream_t * stream=memstream_open(1);
|
||||
assert(stream!=NULL);
|
||||
memstream_rewind(stream);
|
||||
assert(tree!=NULL);
|
||||
tree->serialize(stream); // write to the stream
|
||||
memstream_write(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // write to the stream
|
||||
memstream_write(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
|
||||
memstream_write(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
|
||||
memstream_write(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
|
||||
serializeSize=memstream_pos(stream);
|
||||
memstream_rewind(stream);
|
||||
memstream_read(stream, data_,serializeSize); // read from the stream
|
||||
return true;
|
||||
}
|
||||
bool BotTree::unserialize(const void *data_) {
|
||||
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
|
||||
static memstream_t * stream=memstream_open(1);
|
||||
assert(stream!=NULL);
|
||||
memstream_rewind(stream);
|
||||
memstream_write(stream, data_, serialize_size()); // write to the stream
|
||||
memstream_rewind(stream);
|
||||
assert(tree!=NULL);
|
||||
tree->unserialize(stream);
|
||||
memstream_read(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // read from the stream
|
||||
memstream_read(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
|
||||
memstream_read(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
|
||||
memstream_read(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
|
||||
return true;
|
||||
size_t BotTree::serialize_size(void)
|
||||
{
|
||||
if (serializeSize == 0)
|
||||
{
|
||||
uint8_t tmpBuffer[MEM_STREAM_BUFFER_SIZE];
|
||||
serialize(tmpBuffer);
|
||||
log_error("HARDCODED_RETRO_SERIALIZE_SIZE=SIZE_SER+%d*8\n", serializeSize);
|
||||
}
|
||||
assert(serializeSize != 0);
|
||||
return(serializeSize);
|
||||
}
|
||||
|
||||
bool BotTree::serialize(void *data_)
|
||||
{
|
||||
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
|
||||
static memstream_t *stream = memstream_open(1);
|
||||
assert(stream != NULL);
|
||||
memstream_rewind(stream);
|
||||
assert(tree != NULL);
|
||||
tree->serialize(stream); // write to the stream
|
||||
memstream_write(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // write to the stream
|
||||
memstream_write(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
|
||||
memstream_write(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
|
||||
memstream_write(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
|
||||
serializeSize = memstream_pos(stream);
|
||||
memstream_rewind(stream);
|
||||
memstream_read(stream, data_, serializeSize); // read from the stream
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool BotTree::unserialize(const void *data_)
|
||||
{
|
||||
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
|
||||
static memstream_t *stream = memstream_open(1);
|
||||
assert(stream != NULL);
|
||||
memstream_rewind(stream);
|
||||
memstream_write(stream, data_, serialize_size()); // write to the stream
|
||||
memstream_rewind(stream);
|
||||
assert(tree != NULL);
|
||||
tree->unserialize(stream);
|
||||
memstream_read(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // read from the stream
|
||||
memstream_read(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
|
||||
memstream_read(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
|
||||
memstream_read(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
|
||||
return(true);
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
#include "bt.hpp"
|
||||
#include "Bot.hpp"
|
||||
#define MEM_STREAM_BUFFER_SIZE 64000
|
||||
#define MEM_STREAM_BUFFER_SIZE 64000
|
||||
class BotTree : public Bot {
|
||||
public:
|
||||
BotTree(int playerIndex);
|
||||
size_t serialize_size(void);
|
||||
bool serialize(void *data_);
|
||||
bool unserialize(const void *data_);
|
||||
void updateGrids();
|
||||
void tick();
|
||||
BotTree(int playerIndex);
|
||||
size_t serialize_size(void);
|
||||
bool serialize(void *data_);
|
||||
bool unserialize(const void *data_);
|
||||
void updateGrids();
|
||||
void tick();
|
||||
|
||||
private:
|
||||
bt::BehaviorTree * tree;
|
||||
uint8_t buffer[MEM_STREAM_BUFFER_SIZE];
|
||||
bt::BehaviorTree *tree;
|
||||
uint8_t buffer[MEM_STREAM_BUFFER_SIZE];
|
||||
};
|
||||
|
@ -3,303 +3,449 @@
|
||||
#include "common.hpp"
|
||||
#include "MrboomHelper.hpp"
|
||||
#include <algorithm> // std::min
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
#ifndef DEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#include "assert.h"
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct bombInfo {
|
||||
dd infojoueur;
|
||||
dd countDown;
|
||||
dd offsetCell;
|
||||
dw flameSize;
|
||||
dw remote;
|
||||
dw adderX; //+1,0,-1
|
||||
dw adderY; //+1,0,-1
|
||||
dw offsetX; // 0 = middle
|
||||
dw offsetY;
|
||||
void cell(int cell) {
|
||||
offsetCell=CELLX(cell)+CELLY(cell)*grid_size_x_with_padding;
|
||||
}
|
||||
int x() {
|
||||
return CELLXWITHPADDING(offsetCell);
|
||||
};
|
||||
int y() {
|
||||
return CELLYWITHPADDING(offsetCell);
|
||||
};
|
||||
int getPlayer() {
|
||||
int bombPlayer=-1; //will return -1 on a end of level 2 bomb.
|
||||
if (offsetof(struct Mem,j1)==infojoueur) bombPlayer=0;
|
||||
if (offsetof(struct Mem,j2)==infojoueur) bombPlayer=1;
|
||||
if (offsetof(struct Mem,j3)==infojoueur) bombPlayer=2;
|
||||
if (offsetof(struct Mem,j4)==infojoueur) bombPlayer=3;
|
||||
if (offsetof(struct Mem,j5)==infojoueur) bombPlayer=4;
|
||||
if (offsetof(struct Mem,j6)==infojoueur) bombPlayer=5;
|
||||
if (offsetof(struct Mem,j7)==infojoueur) bombPlayer=6;
|
||||
if (offsetof(struct Mem,j8)==infojoueur) bombPlayer=7;
|
||||
return bombPlayer;
|
||||
}
|
||||
typedef struct bombInfo
|
||||
{
|
||||
dd infojoueur;
|
||||
dd countDown;
|
||||
dd offsetCell;
|
||||
dw flameSize;
|
||||
dw remote;
|
||||
dw adderX; //+1,0,-1
|
||||
dw adderY; //+1,0,-1
|
||||
dw offsetX; // 0 = middle
|
||||
dw offsetY;
|
||||
void cell(int cell)
|
||||
{
|
||||
offsetCell = CELLX(cell) + CELLY(cell) * grid_size_x_with_padding;
|
||||
}
|
||||
|
||||
int x()
|
||||
{
|
||||
return(CELLXWITHPADDING(offsetCell));
|
||||
};
|
||||
int y()
|
||||
{
|
||||
return(CELLYWITHPADDING(offsetCell));
|
||||
};
|
||||
int getPlayer()
|
||||
{
|
||||
int bombPlayer = -1; //will return -1 on a end of level 2 bomb.
|
||||
|
||||
if (offsetof(struct Mem, j1) == infojoueur)
|
||||
{
|
||||
bombPlayer = 0;
|
||||
}
|
||||
if (offsetof(struct Mem, j2) == infojoueur)
|
||||
{
|
||||
bombPlayer = 1;
|
||||
}
|
||||
if (offsetof(struct Mem, j3) == infojoueur)
|
||||
{
|
||||
bombPlayer = 2;
|
||||
}
|
||||
if (offsetof(struct Mem, j4) == infojoueur)
|
||||
{
|
||||
bombPlayer = 3;
|
||||
}
|
||||
if (offsetof(struct Mem, j5) == infojoueur)
|
||||
{
|
||||
bombPlayer = 4;
|
||||
}
|
||||
if (offsetof(struct Mem, j6) == infojoueur)
|
||||
{
|
||||
bombPlayer = 5;
|
||||
}
|
||||
if (offsetof(struct Mem, j7) == infojoueur)
|
||||
{
|
||||
bombPlayer = 6;
|
||||
}
|
||||
if (offsetof(struct Mem, j8) == infojoueur)
|
||||
{
|
||||
bombPlayer = 7;
|
||||
}
|
||||
return(bombPlayer);
|
||||
}
|
||||
} bombInfo;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct travelCostGrid {
|
||||
uint32_t travelCostGrid[grid_size_x][grid_size_y]; // safe to walk walking distance, TRAVELCOST_CANTGO if cant go, -7 to +8 if player is here...
|
||||
uint32_t travelCostGridJumpLeftRight[grid_size_x][grid_size_y];
|
||||
uint32_t travelCostGridJumpUpDown[grid_size_x][grid_size_y];
|
||||
typedef struct travelCostGrid
|
||||
{
|
||||
uint32_t travelCostGrid[grid_size_x][grid_size_y]; // safe to walk walking distance, TRAVELCOST_CANTGO if cant go, -7 to +8 if player is here...
|
||||
uint32_t travelCostGridJumpLeftRight[grid_size_x][grid_size_y];
|
||||
uint32_t travelCostGridJumpUpDown[grid_size_x][grid_size_y];
|
||||
|
||||
uint32_t cost(int i,int j, int direction) const {
|
||||
return std::min(jumpingCost(i,j,direction),travelCostGrid[i][j]); // min: to be able to jump on a flame and come back later using the walking way. (otherwise the comeback breaks the path)
|
||||
}
|
||||
bool wouldInvolveJumping(int i,int j, int direction) const {
|
||||
return (jumpingCost(i,j,direction)<travelCostGrid[i][j]);
|
||||
}
|
||||
uint32_t cost(int i,int j) const {
|
||||
return travelCostGrid[i][j];
|
||||
}
|
||||
uint32_t cost(int cell) const {
|
||||
return cost(CELLX(cell),CELLY(cell));
|
||||
}
|
||||
void setWalkingCost(int cell,uint32_t cost) {
|
||||
travelCostGrid[CELLX(cell)][CELLY(cell)]=cost;
|
||||
}
|
||||
void printCell(int i,int j) {
|
||||
int lr=costLeftRight(i,j);
|
||||
int up=costUpDown(i,j);
|
||||
int w=cost(i,j);
|
||||
uint32_t cost(int i, int j, int direction) const
|
||||
{
|
||||
return(std::min(jumpingCost(i, j, direction), travelCostGrid[i][j])); // min: to be able to jump on a flame and come back later using the walking way. (otherwise the comeback breaks the path)
|
||||
}
|
||||
|
||||
if (TRAVELCOST_CANTGO!=w) {
|
||||
log_debug(" %03d ",w);
|
||||
} else {
|
||||
bool wouldInvolveJumping(int i, int j, int direction) const
|
||||
{
|
||||
return(jumpingCost(i, j, direction) < travelCostGrid[i][j]);
|
||||
}
|
||||
|
||||
if ((lr!=TRAVELCOST_CANTGO) || (up!=TRAVELCOST_CANTGO)) {
|
||||
uint32_t cost(int i, int j) const
|
||||
{
|
||||
return(travelCostGrid[i][j]);
|
||||
}
|
||||
|
||||
uint32_t cost(int cell) const
|
||||
{
|
||||
return(cost(CELLX(cell), CELLY(cell)));
|
||||
}
|
||||
|
||||
if (TRAVELCOST_CANTGO!=lr) {
|
||||
log_debug("%03d/",lr);
|
||||
} else {
|
||||
log_debug("---/");
|
||||
}
|
||||
if (TRAVELCOST_CANTGO!=up) {
|
||||
log_debug("%03d ",up);
|
||||
} else {
|
||||
log_debug("--- ");
|
||||
}
|
||||
void setWalkingCost(int cell, uint32_t cost)
|
||||
{
|
||||
travelCostGrid[CELLX(cell)][CELLY(cell)] = cost;
|
||||
}
|
||||
|
||||
} else {
|
||||
log_debug(" --- ");
|
||||
}
|
||||
void printCell(int i, int j)
|
||||
{
|
||||
int lr = costLeftRight(i, j);
|
||||
int up = costUpDown(i, j);
|
||||
int w = cost(i, j);
|
||||
|
||||
}
|
||||
}
|
||||
if (TRAVELCOST_CANTGO != w)
|
||||
{
|
||||
log_debug(" %03d ", w);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((lr != TRAVELCOST_CANTGO) || (up != TRAVELCOST_CANTGO))
|
||||
{
|
||||
if (TRAVELCOST_CANTGO != lr)
|
||||
{
|
||||
log_debug("%03d/", lr);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("---/");
|
||||
}
|
||||
if (TRAVELCOST_CANTGO != up)
|
||||
{
|
||||
log_debug("%03d ", up);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("--- ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug(" --- ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t jumpingCost(int i, int j, int direction) const
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case button_left:
|
||||
return(travelCostGridJumpLeftRight[i][j]);
|
||||
|
||||
uint32_t jumpingCost(int i,int j,int direction) const {
|
||||
switch (direction) {
|
||||
case button_left:
|
||||
return travelCostGridJumpLeftRight[i][j];
|
||||
break;
|
||||
case button_right:
|
||||
return travelCostGridJumpLeftRight[i][j];
|
||||
break;
|
||||
case button_up:
|
||||
return travelCostGridJumpUpDown[i][j];
|
||||
break;
|
||||
case button_down:
|
||||
return travelCostGridJumpUpDown[i][j];
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint32_t jumpingCost(int cell,int direction) const {
|
||||
int i=CELLX(cell);
|
||||
int j=CELLY(cell);
|
||||
return jumpingCost(i,j,direction);
|
||||
}
|
||||
uint32_t costLeftRight(int i,int j) const {
|
||||
return jumpingCost(i,j,button_left);
|
||||
}
|
||||
break;
|
||||
|
||||
uint32_t costUpDown(int i,int j) const {
|
||||
return jumpingCost(i,j,button_up);
|
||||
}
|
||||
case button_right:
|
||||
return(travelCostGridJumpLeftRight[i][j]);
|
||||
|
||||
void setJumpingCost(int i,int j,uint32_t cost,int direction) {
|
||||
switch (direction) {
|
||||
case button_left:
|
||||
travelCostGridJumpLeftRight[i][j]=cost;
|
||||
break;
|
||||
case button_right:
|
||||
travelCostGridJumpLeftRight[i][j]=cost;
|
||||
break;
|
||||
case button_up:
|
||||
travelCostGridJumpUpDown[i][j]=cost;
|
||||
break;
|
||||
case button_down:
|
||||
travelCostGridJumpUpDown[i][j]=cost;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
void setJumpingCost(int cell,uint32_t cost,int direction) {
|
||||
int i=CELLX(cell);
|
||||
int j=CELLY(cell);
|
||||
return setJumpingCost(i,j,cost,direction);
|
||||
}
|
||||
case button_up:
|
||||
return(travelCostGridJumpUpDown[i][j]);
|
||||
|
||||
bool canWalk(int i,int j) const {
|
||||
return (travelCostGrid[i][j]!=TRAVELCOST_CANTGO);
|
||||
}
|
||||
bool canWalk(int cell) const {
|
||||
return canWalk(CELLX(cell),CELLY(cell));
|
||||
}
|
||||
void init() {
|
||||
for (int j=0; j<grid_size_y; j++)
|
||||
{
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
travelCostGrid[i][j]=TRAVELCOST_CANTGO;
|
||||
travelCostGridJumpLeftRight[i][j]=TRAVELCOST_CANTGO;
|
||||
travelCostGridJumpUpDown[i][j]=TRAVELCOST_CANTGO;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
void print() {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
log_debug("__%03d__ ",i);
|
||||
}
|
||||
log_debug("\n");
|
||||
for (int j=0; j<grid_size_y; j++) {
|
||||
for (int i=0; i<grid_size_x; i++) {
|
||||
printCell(i,j);
|
||||
}
|
||||
log_debug("-%03d-",j);
|
||||
log_debug("\n");
|
||||
}
|
||||
}
|
||||
case button_down:
|
||||
return(travelCostGridJumpUpDown[i][j]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint32_t jumpingCost(int cell, int direction) const
|
||||
{
|
||||
int i = CELLX(cell);
|
||||
int j = CELLY(cell);
|
||||
|
||||
return(jumpingCost(i, j, direction));
|
||||
}
|
||||
|
||||
uint32_t costLeftRight(int i, int j) const
|
||||
{
|
||||
return(jumpingCost(i, j, button_left));
|
||||
}
|
||||
|
||||
uint32_t costUpDown(int i, int j) const
|
||||
{
|
||||
return(jumpingCost(i, j, button_up));
|
||||
}
|
||||
|
||||
void setJumpingCost(int i, int j, uint32_t cost, int direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case button_left:
|
||||
travelCostGridJumpLeftRight[i][j] = cost;
|
||||
break;
|
||||
|
||||
case button_right:
|
||||
travelCostGridJumpLeftRight[i][j] = cost;
|
||||
break;
|
||||
|
||||
case button_up:
|
||||
travelCostGridJumpUpDown[i][j] = cost;
|
||||
break;
|
||||
|
||||
case button_down:
|
||||
travelCostGridJumpUpDown[i][j] = cost;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setJumpingCost(int cell, uint32_t cost, int direction)
|
||||
{
|
||||
int i = CELLX(cell);
|
||||
int j = CELLY(cell);
|
||||
|
||||
return(setJumpingCost(i, j, cost, direction));
|
||||
}
|
||||
|
||||
bool canWalk(int i, int j) const
|
||||
{
|
||||
return(travelCostGrid[i][j] != TRAVELCOST_CANTGO);
|
||||
}
|
||||
|
||||
bool canWalk(int cell) const
|
||||
{
|
||||
return(canWalk(CELLX(cell), CELLY(cell)));
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
travelCostGrid[i][j] = TRAVELCOST_CANTGO;
|
||||
travelCostGridJumpLeftRight[i][j] = TRAVELCOST_CANTGO;
|
||||
travelCostGridJumpUpDown[i][j] = TRAVELCOST_CANTGO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
log_debug("__%03d__ ", i);
|
||||
}
|
||||
log_debug("\n");
|
||||
for (int j = 0; j < grid_size_y; j++)
|
||||
{
|
||||
for (int i = 0; i < grid_size_x; i++)
|
||||
{
|
||||
printCell(i, j);
|
||||
}
|
||||
log_debug("-%03d-", j);
|
||||
log_debug("\n");
|
||||
}
|
||||
}
|
||||
} travelCostGrid;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
enum Button howToGo(int player,int toX,int toY,const travelCostGrid& travelGrid,bool &shouldJump);
|
||||
bool isPlayerFastestToCell(int player, int x,int y);
|
||||
bool isSameTeamTwoFastestToCell(int x,int y);
|
||||
enum Button howToGo(int player, int toX, int toY, const travelCostGrid& travelGrid, bool&shouldJump);
|
||||
bool isPlayerFastestToCell(int player, int x, int y);
|
||||
bool isSameTeamTwoFastestToCell(int x, int y);
|
||||
|
||||
typedef void (*FunctionWithBombInfo)(struct bombInfo *);
|
||||
void iterateOnBombs(FunctionWithBombInfo f);
|
||||
typedef void (*FunctionWithFlameDrawingHelpfulData)(int, int, int, int, uint32_t[grid_size_x][grid_size_y],bool[grid_size_x][grid_size_y],int&);
|
||||
void drawBombFlames(int player, int cell, int flameSize, FunctionWithFlameDrawingHelpfulData f, uint32_t[grid_size_x][grid_size_y],bool[grid_size_x][grid_size_y],int&);
|
||||
void updateBestExplosionGrid(int player, uint32_t bestExplosionsGrid[grid_size_x][grid_size_y], const travelCostGrid& travelGrid,const uint32_t flameGrid[grid_size_x][grid_size_y],const bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
void updateTravelGrid(int player, bool ignoreFlames, travelCostGrid& travelGrid,const uint32_t flameGrid[grid_size_x][grid_size_y],const bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
void updateFlameAndDangerGridsWithBombs(int player,uint32_t flameGrid[grid_size_x][grid_size_y],bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
|
||||
typedef void (*FunctionWithFlameDrawingHelpfulData)(int, int, int, int, uint32_t[grid_size_x][grid_size_y], bool[grid_size_x][grid_size_y], int&);
|
||||
void drawBombFlames(int player, int cell, int flameSize, FunctionWithFlameDrawingHelpfulData f, uint32_t[grid_size_x][grid_size_y], bool[grid_size_x][grid_size_y], int&);
|
||||
void updateBestExplosionGrid(int player, uint32_t bestExplosionsGrid[grid_size_x][grid_size_y], const travelCostGrid& travelGrid, const uint32_t flameGrid[grid_size_x][grid_size_y], const bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
void updateTravelGrid(int player, bool ignoreFlames, travelCostGrid& travelGrid, const uint32_t flameGrid[grid_size_x][grid_size_y], const bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
void updateFlameAndDangerGridsWithBombs(int player, uint32_t flameGrid[grid_size_x][grid_size_y], bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
void updateDangerGridWithMonstersSickPlayersAndCulDeSacs(int player, bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
void updateDangerGridWithMonster4CellsTerritories(bool dangerGrid[grid_size_x][grid_size_y]);
|
||||
|
||||
bool flameInCell(int x,int y);
|
||||
Bonus inline bonusInCell(int x,int y)
|
||||
{
|
||||
/*
|
||||
;1 = bombe... (2,3,4) respirant... si c sup a 4; on est mort...
|
||||
;5 = centre de bombe. de 5 a 11
|
||||
;12 = ligne droite...
|
||||
;19 = arrondie ligne droite vers la gauche...
|
||||
;26 = arrondie ligne droite vers la droite
|
||||
;33 = ligne verti
|
||||
;40 arrondie verti vers le haut
|
||||
;47-- bas
|
||||
;54-- bonus bombe... de 54 a 63 (offset 144)
|
||||
;64-- bonus flamme... de 64 a 73 (offset 144+320*16)
|
||||
;74-- tete de mort de 74 a 83
|
||||
;84-- bonus parre balle. de 84 a 93
|
||||
;94-- bonus COEUR !!!
|
||||
;104 -- bonus bombe retardement
|
||||
;114 --- bonus pousseur
|
||||
;124 --- patins a roulettes
|
||||
;134 --- HORLOGE
|
||||
;horloge
|
||||
bonus_4 134
|
||||
bonus_3 144,1,tribombe
|
||||
bonus_6 154
|
||||
;oeuf
|
||||
bonus_5 193
|
||||
*/
|
||||
db z=m.truc2[x+y*grid_size_x_with_padding];
|
||||
if ((z>=54) && (z<194))
|
||||
{
|
||||
if (z<64) return bonus_bomb;
|
||||
if (z<74) return bonus_flame;
|
||||
if (z<84) return bonus_skull;
|
||||
if (z<94) return bonus_bulletproofjacket;
|
||||
if (z<104) return bonus_heart;
|
||||
if (z<114) return bonus_remote;
|
||||
if (z<124) return bonus_push;
|
||||
if (z<134) return bonus_roller;
|
||||
if (z<144) return bonus_time;
|
||||
if (z<154) return bonus_tribomb;
|
||||
if (z<164) return bonus_banana;
|
||||
return bonus_egg;
|
||||
}
|
||||
bool flameInCell(int x, int y);
|
||||
|
||||
return no_bonus;
|
||||
Bonus inline bonusInCell(int x, int y)
|
||||
{
|
||||
/*
|
||||
* ;1 = bombe... (2,3,4) respirant... si c sup a 4; on est mort...
|
||||
* ;5 = centre de bombe. de 5 a 11
|
||||
* ;12 = ligne droite...
|
||||
* ;19 = arrondie ligne droite vers la gauche...
|
||||
* ;26 = arrondie ligne droite vers la droite
|
||||
* ;33 = ligne verti
|
||||
* ;40 arrondie verti vers le haut
|
||||
* ;47-- bas
|
||||
* ;54-- bonus bombe... de 54 a 63 (offset 144)
|
||||
* ;64-- bonus flamme... de 64 a 73 (offset 144+320*16)
|
||||
* ;74-- tete de mort de 74 a 83
|
||||
* ;84-- bonus parre balle. de 84 a 93
|
||||
* ;94-- bonus COEUR !!!
|
||||
* ;104 -- bonus bombe retardement
|
||||
* ;114 --- bonus pousseur
|
||||
* ;124 --- patins a roulettes
|
||||
* ;134 --- HORLOGE
|
||||
* ;horloge
|
||||
* bonus_4 134
|
||||
* bonus_3 144,1,tribombe
|
||||
* bonus_6 154
|
||||
* ;oeuf
|
||||
* bonus_5 193
|
||||
*/
|
||||
db z = m.truc2[x + y * grid_size_x_with_padding];
|
||||
|
||||
if ((z >= 54) && (z < 194))
|
||||
{
|
||||
if (z < 64)
|
||||
{
|
||||
return(bonus_bomb);
|
||||
}
|
||||
if (z < 74)
|
||||
{
|
||||
return(bonus_flame);
|
||||
}
|
||||
if (z < 84)
|
||||
{
|
||||
return(bonus_skull);
|
||||
}
|
||||
if (z < 94)
|
||||
{
|
||||
return(bonus_bulletproofjacket);
|
||||
}
|
||||
if (z < 104)
|
||||
{
|
||||
return(bonus_heart);
|
||||
}
|
||||
if (z < 114)
|
||||
{
|
||||
return(bonus_remote);
|
||||
}
|
||||
if (z < 124)
|
||||
{
|
||||
return(bonus_push);
|
||||
}
|
||||
if (z < 134)
|
||||
{
|
||||
return(bonus_roller);
|
||||
}
|
||||
if (z < 144)
|
||||
{
|
||||
return(bonus_time);
|
||||
}
|
||||
if (z < 154)
|
||||
{
|
||||
return(bonus_tribomb);
|
||||
}
|
||||
if (z < 164)
|
||||
{
|
||||
return(bonus_banana);
|
||||
}
|
||||
return(bonus_egg);
|
||||
}
|
||||
|
||||
return(no_bonus);
|
||||
}
|
||||
|
||||
|
||||
bool monsterInCell(int x,int y);
|
||||
bool playerInCell(int x,int y);
|
||||
bool enemyInCell(int player,int x,int y);
|
||||
bool enemyAroundCell(int player,int x,int y);
|
||||
bool isCellCulDeSac(int x,int y);
|
||||
bool monsterInCell(int x, int y);
|
||||
bool playerInCell(int x, int y);
|
||||
bool enemyInCell(int player, int x, int y);
|
||||
bool enemyAroundCell(int player, int x, int y);
|
||||
bool isCellCulDeSac(int x, int y);
|
||||
|
||||
extern int lastBombGridUpdate;
|
||||
extern struct bombInfo * bombsGrid[grid_size_x][grid_size_y]; // NULL if no bomb, pointer to the bomb in m.liste_bombe
|
||||
extern struct bombInfo *bombsGrid[grid_size_x][grid_size_y]; // NULL if no bomb, pointer to the bomb in m.liste_bombe
|
||||
|
||||
static void updateBombGrid(struct bombInfo * bomb) {
|
||||
bombsGrid[bomb->x()][bomb->y()]=bomb;
|
||||
static void updateBombGrid(struct bombInfo *bomb)
|
||||
{
|
||||
bombsGrid[bomb->x()][bomb->y()] = bomb;
|
||||
}
|
||||
|
||||
int inline updateBombGrid()
|
||||
{
|
||||
memset(bombsGrid, 0, sizeof(bombsGrid));
|
||||
iterateOnBombs(updateBombGrid);
|
||||
return frameNumber();
|
||||
}
|
||||
bool inline bombInCell(int x,int y)
|
||||
{
|
||||
if ((!lastBombGridUpdate) || (frameNumber()!=lastBombGridUpdate)) lastBombGridUpdate=updateBombGrid();
|
||||
return (bombsGrid[x][y]!=NULL);
|
||||
}
|
||||
bool somethingThatWouldStopFlame(int x,int y);
|
||||
bool inline mudbrickInCell(int x,int y)
|
||||
{
|
||||
db brickKind=m.truc[x+y*grid_size_x_with_padding];
|
||||
return (brickKind==2);
|
||||
memset(bombsGrid, 0, sizeof(bombsGrid));
|
||||
iterateOnBombs(updateBombGrid);
|
||||
return(frameNumber());
|
||||
}
|
||||
|
||||
bool inline brickInCell(int x,int y)
|
||||
bool inline bombInCell(int x, int y)
|
||||
{
|
||||
db brickKind=m.truc[x+y*grid_size_x_with_padding];
|
||||
return ((brickKind==1) || ((brickKind>=3) && (brickKind<=11)));
|
||||
if ((!lastBombGridUpdate) || (frameNumber() != lastBombGridUpdate))
|
||||
{
|
||||
lastBombGridUpdate = updateBombGrid();
|
||||
}
|
||||
return(bombsGrid[x][y] != NULL);
|
||||
}
|
||||
|
||||
bool inline brickOrSkullBonus(int x,int y) {
|
||||
if (brickInCell(x,y))
|
||||
return true;
|
||||
if (mudbrickInCell(x,y))
|
||||
return true;
|
||||
if (bonusInCell(x,y)==bonus_skull)
|
||||
return true;
|
||||
return false;
|
||||
bool somethingThatWouldStopFlame(int x, int y);
|
||||
|
||||
bool inline mudbrickInCell(int x, int y)
|
||||
{
|
||||
db brickKind = m.truc[x + y * grid_size_x_with_padding];
|
||||
|
||||
return(brickKind == 2);
|
||||
}
|
||||
|
||||
bool inline somethingThatIsNoTABombAndThatWouldStopPlayer(int x,int y) {
|
||||
if (brickOrSkullBonus(x,y))
|
||||
return true;
|
||||
if (monsterInCell(x,y))
|
||||
return true;
|
||||
return false;
|
||||
bool inline brickInCell(int x, int y)
|
||||
{
|
||||
db brickKind = m.truc[x + y * grid_size_x_with_padding];
|
||||
|
||||
return((brickKind == 1) || ((brickKind >= 3) && (brickKind <= 11)));
|
||||
}
|
||||
|
||||
bool inline brickOrSkullBonus(int x, int y)
|
||||
{
|
||||
if (brickInCell(x, y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
if (mudbrickInCell(x, y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
if (bonusInCell(x, y) == bonus_skull)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool inline somethingThatIsNoTABombAndThatWouldStopPlayer(int x, int y)
|
||||
{
|
||||
if (brickOrSkullBonus(x, y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
if (monsterInCell(x, y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
void updateMonsterIsComingGrid(bool monsterIsComingGrid[NUMBER_OF_CELLS]);
|
||||
bool canPlayerBeReachedByMonster(int player);
|
||||
bool canPlayerReachEnemy(int player);
|
||||
|
@ -4,373 +4,485 @@
|
||||
|
||||
void addOneAIPlayer()
|
||||
{
|
||||
db * keys=m.total_t;
|
||||
keys[64+5+m.nombre_de_dyna*7]=1;
|
||||
keys[8*7+2]=1;
|
||||
m.nb_ai_bombermen++;
|
||||
db *keys = m.total_t;
|
||||
|
||||
keys[64 + 5 + m.nombre_de_dyna * 7] = 1;
|
||||
keys[8 * 7 + 2] = 1;
|
||||
m.nb_ai_bombermen++;
|
||||
}
|
||||
|
||||
void addXAIPlayers(int x)
|
||||
{
|
||||
db * keys=m.total_t;
|
||||
for (int i=0; i<x; i++) keys[64+5+i*7]=1;
|
||||
keys[8*7+2]=1;
|
||||
db *keys = m.total_t;
|
||||
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
keys[64 + 5 + i * 7] = 1;
|
||||
}
|
||||
keys[8 * 7 + 2] = 1;
|
||||
}
|
||||
|
||||
void pressStart()
|
||||
{
|
||||
db * keys=m.total_t;
|
||||
keys[8*7]=1;
|
||||
keys[8*7+2]=1;
|
||||
db *keys = m.total_t;
|
||||
|
||||
keys[8 * 7] = 1;
|
||||
keys[8 * 7 + 2] = 1;
|
||||
}
|
||||
|
||||
void pressESC()
|
||||
{
|
||||
m.sortie=1;
|
||||
m.sortie = 1;
|
||||
}
|
||||
|
||||
bool isInTheApocalypse() {
|
||||
return (m.in_the_apocalypse==1);
|
||||
bool isInTheApocalypse()
|
||||
{
|
||||
return(m.in_the_apocalypse == 1);
|
||||
}
|
||||
|
||||
bool hasRollers(int player) {
|
||||
return (m.patineur[player]==1);
|
||||
bool hasRollers(int player)
|
||||
{
|
||||
return(m.patineur[player] == 1);
|
||||
}
|
||||
|
||||
bool hasRemote(int player) {
|
||||
return m.j1[4+player*5];
|
||||
bool hasRemote(int player)
|
||||
{
|
||||
return(m.j1[4 + player * 5]);
|
||||
}
|
||||
|
||||
bool hasPush(int player) {
|
||||
return (m.pousseur[player]==1);
|
||||
bool hasPush(int player)
|
||||
{
|
||||
return(m.pousseur[player] == 1);
|
||||
}
|
||||
bool hasTriBomb(int player) {
|
||||
return (m.tribombe[player]==1);
|
||||
|
||||
bool hasTriBomb(int player)
|
||||
{
|
||||
return(m.tribombe[player] == 1);
|
||||
}
|
||||
|
||||
// Warning will be zero if less then 1
|
||||
int pixelsPerFrame(int player) {
|
||||
return CELLPIXELSSIZE/framesToCrossACell(player);
|
||||
int pixelsPerFrame(int player)
|
||||
{
|
||||
return(CELLPIXELSSIZE / framesToCrossACell(player));
|
||||
}
|
||||
|
||||
int framesToCrossACell(int player)
|
||||
{
|
||||
bool speed=hasSpeedDisease(player);
|
||||
bool slow=hasSlowDisease(player);
|
||||
if (hasRollers(player))
|
||||
{
|
||||
if (slow)
|
||||
return (CELLPIXELSSIZE/2)*4; //32
|
||||
if (speed)
|
||||
return (CELLPIXELSSIZE/2)/4; //2
|
||||
return CELLPIXELSSIZE/2; //8
|
||||
}
|
||||
bool speed = hasSpeedDisease(player);
|
||||
bool slow = hasSlowDisease(player);
|
||||
|
||||
if (slow)
|
||||
return CELLPIXELSSIZE*4; //64
|
||||
if (speed)
|
||||
return CELLPIXELSSIZE/4; //4
|
||||
return CELLPIXELSSIZE; //16
|
||||
if (hasRollers(player))
|
||||
{
|
||||
if (slow)
|
||||
{
|
||||
return((CELLPIXELSSIZE / 2) * 4); //32
|
||||
}
|
||||
if (speed)
|
||||
{
|
||||
return((CELLPIXELSSIZE / 2) / 4); //2
|
||||
}
|
||||
return(CELLPIXELSSIZE / 2); //8
|
||||
}
|
||||
|
||||
if (slow)
|
||||
{
|
||||
return(CELLPIXELSSIZE * 4); //64
|
||||
}
|
||||
if (speed)
|
||||
{
|
||||
return(CELLPIXELSSIZE / 4); //4
|
||||
}
|
||||
return(CELLPIXELSSIZE); //16
|
||||
}
|
||||
|
||||
int nbLives(int player) {
|
||||
if (isAlive(player)) {
|
||||
return (m.nombre_de_coups[player]+1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
int nbLives(int player)
|
||||
{
|
||||
if (isAlive(player))
|
||||
{
|
||||
return(m.nombre_de_coups[player] + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool isAlive(int player)
|
||||
{
|
||||
return (m.vie[player]==1);
|
||||
return(m.vie[player] == 1);
|
||||
}
|
||||
|
||||
bool isAIActiveForPlayer(int player)
|
||||
{
|
||||
return ((m.control_joueur[player]>=64) && (m.control_joueur[player]<=64*2));
|
||||
return((m.control_joueur[player] >= 64) && (m.control_joueur[player] <= 64 * 2));
|
||||
}
|
||||
|
||||
bool hasAnyDisease(int player) {
|
||||
return (m.maladie[player*2]!=0);
|
||||
bool hasAnyDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] != 0);
|
||||
}
|
||||
|
||||
bool hasSlowDisease(int player) {
|
||||
return (m.maladie[player*2]==2);
|
||||
bool hasSlowDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 2);
|
||||
}
|
||||
|
||||
bool hasSpeedDisease(int player) {
|
||||
return (m.maladie[player*2]==1);
|
||||
bool hasSpeedDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 1);
|
||||
}
|
||||
|
||||
bool hasInvertedDisease(int player) {
|
||||
return (m.maladie[player*2]==4);
|
||||
bool hasInvertedDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 4);
|
||||
}
|
||||
|
||||
bool hasDiarrheaDisease(int player) {
|
||||
return (m.maladie[player*2]==3);
|
||||
}
|
||||
bool hasSmallBombDisease(int player) {
|
||||
return (m.maladie[player*2]==6);
|
||||
}
|
||||
bool hasConstipationDisease(int player) {
|
||||
return (m.maladie[player*2]==5);
|
||||
bool hasDiarrheaDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 3);
|
||||
}
|
||||
|
||||
void setDisease(int player, int disease, int duration) {
|
||||
m.maladie[player*2]=disease;
|
||||
m.maladie[player*2+1]=duration;
|
||||
bool hasSmallBombDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 6);
|
||||
}
|
||||
|
||||
bool hasConstipationDisease(int player)
|
||||
{
|
||||
return(m.maladie[player * 2] == 5);
|
||||
}
|
||||
|
||||
void setDisease(int player, int disease, int duration)
|
||||
{
|
||||
m.maladie[player * 2] = disease;
|
||||
m.maladie[player * 2 + 1] = duration;
|
||||
}
|
||||
|
||||
int numberOfPlayers()
|
||||
{
|
||||
return m.nombre_de_dyna;
|
||||
}
|
||||
bool replay() {
|
||||
return m.action_replay!=0;
|
||||
return(m.nombre_de_dyna);
|
||||
}
|
||||
|
||||
int level() {
|
||||
if (replay()) return -1;
|
||||
if (inTheMenu()) return -1;
|
||||
return m.viseur_liste_terrain;
|
||||
bool replay()
|
||||
{
|
||||
return(m.action_replay != 0);
|
||||
}
|
||||
|
||||
int level()
|
||||
{
|
||||
if (replay())
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
if (inTheMenu())
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
return(m.viseur_liste_terrain);
|
||||
}
|
||||
|
||||
void chooseLevel(int level)
|
||||
{
|
||||
m.viseur_liste_terrain=level;
|
||||
m.viseur_liste_terrain = level;
|
||||
}
|
||||
|
||||
bool inTheMenu() {
|
||||
return((isGameActive()==false) && m.ordre=='S');
|
||||
bool inTheMenu()
|
||||
{
|
||||
return((isGameActive() == false) && m.ordre == 'S');
|
||||
}
|
||||
|
||||
bool isGameActive()
|
||||
{
|
||||
if ((m.ordre==1) && (m.ordre2==3))
|
||||
return true;
|
||||
return false;
|
||||
if ((m.ordre == 1) && (m.ordre2 == 3))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool isAboutToWin() {
|
||||
return (m.attente_avant_med<100);
|
||||
bool isAboutToWin()
|
||||
{
|
||||
return(m.attente_avant_med < 100);
|
||||
}
|
||||
|
||||
int nbBombsLeft(int player)
|
||||
{
|
||||
if (m.nombre_de_vbl_avant_le_droit_de_poser_bombe)
|
||||
return 0;
|
||||
if (hasConstipationDisease(player))
|
||||
return 0;
|
||||
if (isAboutToWin())
|
||||
return 0;
|
||||
return m.j1[player*5]; //nb of bombs
|
||||
if (m.nombre_de_vbl_avant_le_droit_de_poser_bombe)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
if (hasConstipationDisease(player))
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
if (isAboutToWin())
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
return(m.j1[player * 5]); //nb of bombs
|
||||
}
|
||||
|
||||
void activeApocalypse()
|
||||
{
|
||||
m.temps=2;
|
||||
m.temps = 2;
|
||||
}
|
||||
|
||||
int invincibility(int player) {
|
||||
return m.invinsible[player];
|
||||
int invincibility(int player)
|
||||
{
|
||||
return(m.invinsible[player]);
|
||||
}
|
||||
|
||||
|
||||
void activeCheatMode()
|
||||
{
|
||||
log_info("activeCheatMode\n");
|
||||
m.temps=816;
|
||||
for (db i=0; i<nb_dyna; i++)
|
||||
{
|
||||
// setDisease(i,3,1000); Diarrhea
|
||||
/*
|
||||
if (i>= m.nombre_de_dyna)
|
||||
m.nombre_de_coups[i]=1; //number of lifes
|
||||
else
|
||||
m.nombre_de_coups[i]=99;
|
||||
*/
|
||||
log_info("activeCheatMode\n");
|
||||
m.temps = 816;
|
||||
for (db i = 0; i < nb_dyna; i++)
|
||||
{
|
||||
// setDisease(i,3,1000); Diarrhea
|
||||
|
||||
if (i< m.nombre_de_dyna) {
|
||||
m.j1[i*5]=1; //nb of bombs
|
||||
//m.j1[1+i*5]=5; // power of bombs
|
||||
m.j1[4+i*5]=1; // remote
|
||||
m.pousseur[i]=1; // bomb pusher
|
||||
m.lapipipino[i]=1;
|
||||
m.nombre_de_coups[i]++;
|
||||
}
|
||||
}
|
||||
setNoMonsterMode(true);
|
||||
/*
|
||||
* if (i>= m.nombre_de_dyna)
|
||||
* m.nombre_de_coups[i]=1; //number of lifes
|
||||
* else
|
||||
* m.nombre_de_coups[i]=99;
|
||||
*/
|
||||
|
||||
if (i < m.nombre_de_dyna)
|
||||
{
|
||||
m.j1[i * 5] = 1; //nb of bombs
|
||||
//m.j1[1+i*5]=5; // power of bombs
|
||||
m.j1[4 + i * 5] = 1; // remote
|
||||
m.pousseur[i] = 1; // bomb pusher
|
||||
m.lapipipino[i] = 1;
|
||||
m.nombre_de_coups[i]++;
|
||||
}
|
||||
}
|
||||
setNoMonsterMode(true);
|
||||
}
|
||||
|
||||
void setNoMonsterMode(bool on)
|
||||
{
|
||||
m.nomonster=on;
|
||||
m.nomonster = on;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool bonusPlayerWouldLike(int player,enum Bonus bonus)
|
||||
bool bonusPlayerWouldLike(int player, enum Bonus bonus)
|
||||
{
|
||||
switch (bonus)
|
||||
{
|
||||
case no_bonus:
|
||||
case bonus_skull:
|
||||
case bonus_time:
|
||||
return false;
|
||||
case bonus_roller:
|
||||
return (hasRollers(player)==false);
|
||||
case bonus_remote:
|
||||
return (hasRemote(player)==false);
|
||||
case bonus_tribomb:
|
||||
return false;
|
||||
switch (bonus)
|
||||
{
|
||||
case no_bonus:
|
||||
case bonus_skull:
|
||||
case bonus_time:
|
||||
return(false);
|
||||
|
||||
case bonus_roller:
|
||||
return(hasRollers(player) == false);
|
||||
|
||||
case bonus_remote:
|
||||
return(hasRemote(player) == false);
|
||||
|
||||
case bonus_tribomb:
|
||||
return(false);
|
||||
|
||||
// return (hasTriBomb(player)==false);
|
||||
case bonus_push:
|
||||
return (hasPush(player)==false);
|
||||
case bonus_egg:
|
||||
return (hasKangaroo(player)==false);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
case bonus_push:
|
||||
return(hasPush(player) == false);
|
||||
|
||||
case bonus_egg:
|
||||
return(hasKangaroo(player) == false);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
void setFrameNumber(int frame) {
|
||||
m.changement=frame;
|
||||
void setFrameNumber(int frame)
|
||||
{
|
||||
m.changement = frame;
|
||||
}
|
||||
|
||||
int flameSize(int player)
|
||||
{
|
||||
if (hasSmallBombDisease(player))
|
||||
return 1;
|
||||
return m.j1[1+player*5];
|
||||
if (hasSmallBombDisease(player))
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
return(m.j1[1 + player * 5]);
|
||||
}
|
||||
|
||||
void setTeamMode(int teamMode) {
|
||||
m.team3_sauve=teamMode;
|
||||
void setTeamMode(int teamMode)
|
||||
{
|
||||
m.team3_sauve = teamMode;
|
||||
}
|
||||
|
||||
int teamMode() {
|
||||
return m.team3_sauve;
|
||||
int teamMode()
|
||||
{
|
||||
return(m.team3_sauve);
|
||||
}
|
||||
|
||||
void setAutofire(bool on) {
|
||||
if (on) {
|
||||
m.autofire=1;
|
||||
} else {
|
||||
m.autofire=0;
|
||||
}
|
||||
void setAutofire(bool on)
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
m.autofire = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.autofire = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool autofire() {
|
||||
return (m.autofire==1);
|
||||
bool autofire()
|
||||
{
|
||||
return(m.autofire == 1);
|
||||
}
|
||||
|
||||
int xPlayer(int player) {
|
||||
return (m.donnee[player]+DELTA_X)/CELLPIXELSSIZE;
|
||||
}
|
||||
int yPlayer(int player) {
|
||||
return (m.donnee[nb_dyna+player]+DELTA_Y)/CELLPIXELSSIZE;
|
||||
int xPlayer(int player)
|
||||
{
|
||||
return((m.donnee[player] + DELTA_X) / CELLPIXELSSIZE);
|
||||
}
|
||||
|
||||
int cellPlayer(int player) {
|
||||
return (xPlayer(player)+yPlayer(player)*grid_size_x);
|
||||
int yPlayer(int player)
|
||||
{
|
||||
return((m.donnee[nb_dyna + player] + DELTA_Y) / CELLPIXELSSIZE);
|
||||
}
|
||||
|
||||
bool tracesDecisions(int player) {
|
||||
return(debugTracesPlayer(player) && (traceMask & DEBUG_MASK_BOTTREEDECISIONS));
|
||||
int cellPlayer(int player)
|
||||
{
|
||||
return(xPlayer(player) + yPlayer(player) * grid_size_x);
|
||||
}
|
||||
|
||||
bool isInMiddleOfCell(int player) {
|
||||
int step=pixelsPerFrame(player);
|
||||
assert(step<=MAX_PIXELS_PER_FRAME);
|
||||
int x=GETXPIXELSTOCENTEROFCELL(player);
|
||||
int y=GETYPIXELSTOCENTEROFCELL(player);
|
||||
if (step<1)
|
||||
return ((!x) && (!y));
|
||||
return ((x>=-step/2) && (x<=step/2) && (y<=step/2) && (y>=-step/2));
|
||||
bool tracesDecisions(int player)
|
||||
{
|
||||
return(debugTracesPlayer(player) && (traceMask & DEBUG_MASK_BOTTREEDECISIONS));
|
||||
}
|
||||
|
||||
int dangerousCellForMonster(int player) {
|
||||
int cell=cellPlayer(player);
|
||||
int index=m.viseur_change_in[player]/4;
|
||||
index--;
|
||||
if (index<0) {
|
||||
index=15;
|
||||
}
|
||||
switch (m.changeiny[index]) {
|
||||
case 0:
|
||||
return cell+grid_size_x;
|
||||
case 8:
|
||||
return cell+1;
|
||||
case 16:
|
||||
return cell-1;
|
||||
case 24:
|
||||
return cell-grid_size_x;
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
bool isInMiddleOfCell(int player)
|
||||
{
|
||||
int step = pixelsPerFrame(player);
|
||||
|
||||
assert(step <= MAX_PIXELS_PER_FRAME);
|
||||
int x = GETXPIXELSTOCENTEROFCELL(player);
|
||||
int y = GETYPIXELSTOCENTEROFCELL(player);
|
||||
if (step < 1)
|
||||
{
|
||||
return((!x) && (!y));
|
||||
}
|
||||
return((x >= -step / 2) && (x <= step / 2) && (y <= step / 2) && (y >= -step / 2));
|
||||
}
|
||||
|
||||
int victories(int player) {
|
||||
int mode = teamMode();
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
return m.victoires[player];
|
||||
break;
|
||||
case 1: // color mode
|
||||
return m.victoires[player/2];
|
||||
break;
|
||||
int dangerousCellForMonster(int player)
|
||||
{
|
||||
int cell = cellPlayer(player);
|
||||
int index = m.viseur_change_in[player] / 4;
|
||||
|
||||
case 2: // sex mode
|
||||
return m.victoires[player%2];
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void pauseGameButton() {
|
||||
if (m.pauseur2) {
|
||||
m.pauseur2=0;
|
||||
index--;
|
||||
if (index < 0)
|
||||
{
|
||||
index = 15;
|
||||
}
|
||||
switch (m.changeiny[index])
|
||||
{
|
||||
case 0:
|
||||
return(cell + grid_size_x);
|
||||
|
||||
} else {
|
||||
m.pauseur2=4;
|
||||
}
|
||||
case 8:
|
||||
return(cell + 1);
|
||||
|
||||
case 16:
|
||||
return(cell - 1);
|
||||
|
||||
case 24:
|
||||
return(cell - grid_size_x);
|
||||
}
|
||||
assert(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool isGamePaused() {
|
||||
return m.pauseur2;
|
||||
int victories(int player)
|
||||
{
|
||||
int mode = teamMode();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
return(m.victoires[player]);
|
||||
|
||||
break;
|
||||
|
||||
case 1: // color mode
|
||||
return(m.victoires[player / 2]);
|
||||
|
||||
break;
|
||||
|
||||
case 2: // sex mode
|
||||
return(m.victoires[player % 2]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool isSuicideOK(int player) {
|
||||
int myTeam=teamOfPlayer(player);
|
||||
int nbLivesEnemies=0;
|
||||
int nbLivesFriends=0;
|
||||
for (int i=0; i<numberOfPlayers(); i++) {
|
||||
if (myTeam==teamOfPlayer(i)) {
|
||||
nbLivesFriends+=nbLives(i);
|
||||
if (invincibility(i)) nbLivesFriends++;
|
||||
}
|
||||
if (myTeam!=teamOfPlayer(i)) {
|
||||
nbLivesEnemies+=nbLives(i);
|
||||
if (invincibility(i)) nbLivesEnemies++;
|
||||
}
|
||||
}
|
||||
return ((nbLivesFriends>1) && (nbLivesEnemies==1));
|
||||
void pauseGameButton()
|
||||
{
|
||||
if (m.pauseur2)
|
||||
{
|
||||
m.pauseur2 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m.pauseur2 = 4;
|
||||
}
|
||||
}
|
||||
|
||||
bool someHumanPlayersAlive() {
|
||||
for (int i=0; i<numberOfPlayers(); i++) {
|
||||
if (isAIActiveForPlayer(i)==false) {
|
||||
if (isAlive(i)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
bool isGamePaused()
|
||||
{
|
||||
return(m.pauseur2);
|
||||
}
|
||||
|
||||
bool isSuicideOK(int player)
|
||||
{
|
||||
int myTeam = teamOfPlayer(player);
|
||||
int nbLivesEnemies = 0;
|
||||
int nbLivesFriends = 0;
|
||||
|
||||
for (int i = 0; i < numberOfPlayers(); i++)
|
||||
{
|
||||
if (myTeam == teamOfPlayer(i))
|
||||
{
|
||||
nbLivesFriends += nbLives(i);
|
||||
if (invincibility(i))
|
||||
{
|
||||
nbLivesFriends++;
|
||||
}
|
||||
}
|
||||
if (myTeam != teamOfPlayer(i))
|
||||
{
|
||||
nbLivesEnemies += nbLives(i);
|
||||
if (invincibility(i))
|
||||
{
|
||||
nbLivesEnemies++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return((nbLivesFriends > 1) && (nbLivesEnemies == 1));
|
||||
}
|
||||
|
||||
bool someHumanPlayersAlive()
|
||||
{
|
||||
for (int i = 0; i < numberOfPlayers(); i++)
|
||||
{
|
||||
if (isAIActiveForPlayer(i) == false)
|
||||
{
|
||||
if (isAlive(i))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
@ -2,43 +2,48 @@
|
||||
#include <stdint.h>
|
||||
#include "mrboom.h"
|
||||
#include "common.hpp"
|
||||
#ifndef DEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#include "assert.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DELTA_X 3
|
||||
#define DELTA_Y 14
|
||||
#define COUNTDOWN_DURATON 256
|
||||
#define CELLPIXELSSIZE 16
|
||||
#define grid_size_x_with_padding (32)
|
||||
#define grid_size_x (grid_size_x_with_padding-13)
|
||||
#define grid_size_y (13)
|
||||
#define NUMBER_OF_CELLS (grid_size_x*grid_size_y)
|
||||
#define GETXPIXELSTOCENTEROFCELL(player) (-7+((m.donnee[player]+DELTA_X)%CELLPIXELSSIZE))
|
||||
#define GETYPIXELSTOCENTEROFCELL(player) (-7+((m.donnee[nb_dyna+player]+DELTA_Y)%CELLPIXELSSIZE))
|
||||
#define CELLINDEX(cellx,celly) (((celly)*grid_size_x)+(cellx))
|
||||
#define CELLX(cell) (cell%grid_size_x)
|
||||
#define CELLY(cell) (cell/grid_size_x)
|
||||
#define CELLXWITHPADDING(cell) (cell%grid_size_x_with_padding)
|
||||
#define CELLYWITHPADDING(cell) (cell/grid_size_x_with_padding)
|
||||
#define TRAVELCOST_CANTGO 9999
|
||||
#define FLAME_DURATION (16*5+6*4*2)
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
#define DELTA_X 3
|
||||
#define DELTA_Y 14
|
||||
#define COUNTDOWN_DURATON 256
|
||||
#define CELLPIXELSSIZE 16
|
||||
#define grid_size_x_with_padding (32)
|
||||
#define grid_size_x (grid_size_x_with_padding - 13)
|
||||
#define grid_size_y (13)
|
||||
#define NUMBER_OF_CELLS (grid_size_x * grid_size_y)
|
||||
#define GETXPIXELSTOCENTEROFCELL(player) (-7 + ((m.donnee[player] + DELTA_X) % CELLPIXELSSIZE))
|
||||
#define GETYPIXELSTOCENTEROFCELL(player) (-7 + ((m.donnee[nb_dyna + player] + DELTA_Y) % CELLPIXELSSIZE))
|
||||
#define CELLINDEX(cellx, celly) (((celly) * grid_size_x) + (cellx))
|
||||
#define CELLX(cell) (cell % grid_size_x)
|
||||
#define CELLY(cell) (cell / grid_size_x)
|
||||
#define CELLXWITHPADDING(cell) (cell % grid_size_x_with_padding)
|
||||
#define CELLYWITHPADDING(cell) (cell / grid_size_x_with_padding)
|
||||
#define TRAVELCOST_CANTGO 9999
|
||||
#define FLAME_DURATION (16 * 5 + 6 * 4 * 2)
|
||||
#define MAX_PIXELS_PER_FRAME 8
|
||||
|
||||
enum Bonus {
|
||||
no_bonus,
|
||||
bonus_bomb,
|
||||
bonus_flame,
|
||||
bonus_skull,
|
||||
bonus_bulletproofjacket,
|
||||
bonus_heart,
|
||||
bonus_remote,
|
||||
bonus_push,
|
||||
bonus_roller,
|
||||
bonus_time,
|
||||
bonus_tribomb,
|
||||
bonus_banana,
|
||||
bonus_egg
|
||||
enum Bonus
|
||||
{
|
||||
no_bonus,
|
||||
bonus_bomb,
|
||||
bonus_flame,
|
||||
bonus_skull,
|
||||
bonus_bulletproofjacket,
|
||||
bonus_heart,
|
||||
bonus_remote,
|
||||
bonus_push,
|
||||
bonus_roller,
|
||||
bonus_time,
|
||||
bonus_tribomb,
|
||||
bonus_banana,
|
||||
bonus_egg
|
||||
};
|
||||
|
||||
bool someHumanPlayersAlive();
|
||||
@ -49,9 +54,12 @@ void addOneAIPlayer();
|
||||
void addXAIPlayers(int x);
|
||||
void pressStart();
|
||||
void pressESC();
|
||||
bool inline hasKangaroo(int player) {
|
||||
return (m.lapipipino[player]==1);
|
||||
|
||||
bool inline hasKangaroo(int player)
|
||||
{
|
||||
return(m.lapipipino[player] == 1);
|
||||
}
|
||||
|
||||
bool hasRemote(int player);
|
||||
bool hasRollers(int player);
|
||||
bool hasPush(int player);
|
||||
@ -65,7 +73,7 @@ bool hasSmallBombDisease(int player);
|
||||
bool hasConstipationDisease(int player);
|
||||
void setDisease(int player, int disease, int duration);
|
||||
int nbBombsLeft(int player);
|
||||
bool bonusPlayerWouldLike(int player,enum Bonus bonus);
|
||||
bool bonusPlayerWouldLike(int player, enum Bonus bonus);
|
||||
int numberOfPlayers();
|
||||
bool inTheMenu();
|
||||
bool isGameActive();
|
||||
@ -76,9 +84,12 @@ void setNoMonsterMode(bool on);
|
||||
int invincibility(int player);
|
||||
int framesToCrossACell(int player);
|
||||
int pixelsPerFrame(int player);
|
||||
int inline frameNumber() {
|
||||
return m.changement;
|
||||
|
||||
int inline frameNumber()
|
||||
{
|
||||
return(m.changement);
|
||||
}
|
||||
|
||||
void setFrameNumber(int frame);
|
||||
int flameSize(int player);
|
||||
void chooseLevel(int level);
|
||||
@ -97,52 +108,60 @@ bool tracesDecisions(int player);
|
||||
bool isInMiddleOfCell(int player);
|
||||
int dangerousCellForMonster(int player);
|
||||
int victories(int player);
|
||||
int inline getAdderX(int player) {
|
||||
return GETXPIXELSTOCENTEROFCELL(player)*framesToCrossACell(player)/CELLPIXELSSIZE;
|
||||
|
||||
int inline getAdderX(int player)
|
||||
{
|
||||
return(GETXPIXELSTOCENTEROFCELL(player) * framesToCrossACell(player) / CELLPIXELSSIZE);
|
||||
}
|
||||
int inline getAdderY(int player) {
|
||||
return GETYPIXELSTOCENTEROFCELL(player)*framesToCrossACell(player)/CELLPIXELSSIZE;
|
||||
|
||||
int inline getAdderY(int player)
|
||||
{
|
||||
return(GETYPIXELSTOCENTEROFCELL(player) * framesToCrossACell(player) / CELLPIXELSSIZE);
|
||||
}
|
||||
|
||||
bool isSuicideOK(int player);
|
||||
int nbLives(int player);
|
||||
|
||||
|
||||
enum playerKind
|
||||
{
|
||||
player_team1 = 1,
|
||||
player_team2 = 2,
|
||||
player_team3 = 4,
|
||||
player_team4 = 8,
|
||||
player_team5 = 16,
|
||||
player_team6 = 32,
|
||||
player_team7 = 64,
|
||||
player_team8 = 128,
|
||||
monster_team = 256
|
||||
player_team1 = 1,
|
||||
player_team2 = 2,
|
||||
player_team3 = 4,
|
||||
player_team4 = 8,
|
||||
player_team5 = 16,
|
||||
player_team6 = 32,
|
||||
player_team7 = 64,
|
||||
player_team8 = 128,
|
||||
monster_team = 256
|
||||
};
|
||||
|
||||
enum playerKind inline teamOfPlayer(int player)
|
||||
{
|
||||
enum playerKind result=monster_team;
|
||||
int mode = teamMode();
|
||||
enum playerKind result = monster_team;
|
||||
int mode = teamMode();
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
result=static_cast<playerKind>(1 << player);
|
||||
break;
|
||||
case 1: // color mode
|
||||
result=static_cast<playerKind>(1 << player/2);
|
||||
break;
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
result = static_cast <playerKind>(1 << player);
|
||||
break;
|
||||
|
||||
case 2: // sex mode
|
||||
result=static_cast<playerKind>(1 << player%2);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
case 1: // color mode
|
||||
result = static_cast <playerKind>(1 << player / 2);
|
||||
break;
|
||||
|
||||
case 2: // sex mode
|
||||
result = static_cast <playerKind>(1 << player % 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
19
ai/README.md
19
ai/README.md
@ -1,11 +1,12 @@
|
||||
![alt tag](../tests/screenshots/mrboom-0.gif)
|
||||
![alt tag](../tests/screenshots/mrboom-1.gif)
|
||||
![alt tag](../tests/screenshots/mrboom-2.gif)
|
||||
![alt tag](../tests/screenshots/mrboom-3.gif)
|
||||
![alt tag](../tests/screenshots/mrboom-4.gif)
|
||||
![alt tag](../tests/screenshots/mrboom-5.gif)
|
||||
![alt tag](../tests/screenshots/mrboom-6.gif)
|
||||
![alt tag](../tests/screenshots/mrboom-7.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 0.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 1.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 2.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 3.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 4.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 5.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 6.gif)
|
||||
![alt tag](../ tests / screenshots / mrboom - 7.gif)
|
||||
![alt tag](bt.png)
|
||||
|
||||
Using a c++98 port of arvidsson's [behavior tree library](https://github.com/arvidsson/bt).
|
||||
Using a c++ 98 port of arvidsson 's [behavior tree library](https://github.com/arvidsson/bt).
|
||||
|
||||
|
@ -8,4 +8,3 @@
|
||||
// composites
|
||||
#include "bt/composites/Selector.hpp"
|
||||
#include "bt/composites/Sequence.hpp"
|
||||
|
||||
|
@ -4,35 +4,40 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
class BehaviorTree : public Node
|
||||
{
|
||||
public:
|
||||
BehaviorTree() {
|
||||
root = NULL;
|
||||
}
|
||||
BehaviorTree(Node * rootNode) {
|
||||
root = rootNode;
|
||||
}
|
||||
BehaviorTree()
|
||||
{
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
Status Update() {
|
||||
return root->Tick();
|
||||
}
|
||||
BehaviorTree(Node *rootNode)
|
||||
{
|
||||
root = rootNode;
|
||||
}
|
||||
|
||||
void SetRoot(Node * node) {
|
||||
root = node;
|
||||
}
|
||||
Status Update()
|
||||
{
|
||||
return(root->Tick());
|
||||
}
|
||||
|
||||
void serialize(memstream_t * stream) {
|
||||
root->serialize(stream);
|
||||
}
|
||||
void SetRoot(Node *node)
|
||||
{
|
||||
root = node;
|
||||
}
|
||||
|
||||
void unserialize(memstream_t * stream) {
|
||||
root->unserialize(stream);
|
||||
}
|
||||
void serialize(memstream_t *stream)
|
||||
{
|
||||
root->serialize(stream);
|
||||
}
|
||||
|
||||
void unserialize(memstream_t *stream)
|
||||
{
|
||||
root->unserialize(stream);
|
||||
}
|
||||
|
||||
private:
|
||||
Node * root;
|
||||
Node *root;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -4,49 +4,60 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
class Composite : public Node
|
||||
{
|
||||
public:
|
||||
|
||||
Composite() {
|
||||
index = 0;
|
||||
}
|
||||
virtual ~Composite() {
|
||||
}
|
||||
Composite()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
void AddChild(Node * child) {
|
||||
children.push_back(child);
|
||||
}
|
||||
bool HasNoChildren() const {
|
||||
return children.empty();
|
||||
}
|
||||
int GetIndex() const {
|
||||
return index;
|
||||
}
|
||||
virtual ~Composite()
|
||||
{
|
||||
}
|
||||
|
||||
void serialize(memstream_t * stream) {
|
||||
// TOFIX big endian
|
||||
Node::serialize(stream);
|
||||
memstream_write(stream, &index, sizeof(index));
|
||||
for (int i=0; i<(signed)children.size(); i++) {
|
||||
bt::Node * child = children.at(i);
|
||||
child->serialize(stream);
|
||||
}
|
||||
}
|
||||
void unserialize(memstream_t * stream) {
|
||||
// TOFIX big endian
|
||||
Node::unserialize(stream);
|
||||
memstream_read(stream, &index, sizeof(index));
|
||||
for (int i=0; i<(signed)children.size(); i++) {
|
||||
bt::Node * child = children.at(i);
|
||||
child->unserialize(stream);
|
||||
}
|
||||
}
|
||||
void AddChild(Node *child)
|
||||
{
|
||||
children.push_back(child);
|
||||
}
|
||||
|
||||
bool HasNoChildren() const
|
||||
{
|
||||
return(children.empty());
|
||||
}
|
||||
|
||||
int GetIndex() const
|
||||
{
|
||||
return(index);
|
||||
}
|
||||
|
||||
void serialize(memstream_t *stream)
|
||||
{
|
||||
// TOFIX big endian
|
||||
Node::serialize(stream);
|
||||
memstream_write(stream, &index, sizeof(index));
|
||||
for (int i = 0; i < (signed)children.size(); i++)
|
||||
{
|
||||
bt::Node *child = children.at(i);
|
||||
child->serialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void unserialize(memstream_t *stream)
|
||||
{
|
||||
// TOFIX big endian
|
||||
Node::unserialize(stream);
|
||||
memstream_read(stream, &index, sizeof(index));
|
||||
for (int i = 0; i < (signed)children.size(); i++)
|
||||
{
|
||||
bt::Node *child = children.at(i);
|
||||
child->unserialize(stream);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<Node *> children;
|
||||
uint8_t index;
|
||||
std::vector <Node *> children;
|
||||
uint8_t index;
|
||||
};
|
||||
|
||||
}
|
||||
|
122
ai/bt/Node.hpp
122
ai/bt/Node.hpp
@ -6,75 +6,97 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
enum Status
|
||||
{
|
||||
Invalid,
|
||||
Success,
|
||||
Failure,
|
||||
Running
|
||||
Invalid,
|
||||
Success,
|
||||
Failure,
|
||||
Running
|
||||
};
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
|
||||
Node() {
|
||||
status = Invalid;
|
||||
}
|
||||
Node()
|
||||
{
|
||||
status = Invalid;
|
||||
}
|
||||
|
||||
virtual ~Node() {
|
||||
}
|
||||
virtual ~Node()
|
||||
{
|
||||
}
|
||||
|
||||
virtual Status Update() = 0;
|
||||
virtual void Initialize() {
|
||||
}
|
||||
virtual void Terminate(Status s) {
|
||||
}
|
||||
virtual Status Update() = 0;
|
||||
|
||||
virtual void serialize(memstream_t * stream) {
|
||||
uint8_t s=(uint8_t) status;
|
||||
memstream_write(stream, &s, sizeof(s));
|
||||
}
|
||||
virtual void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void unserialize(memstream_t * stream) {
|
||||
uint8_t s;
|
||||
memstream_read(stream, &s, sizeof(s));
|
||||
status=bt::Status(s);
|
||||
}
|
||||
virtual void Terminate(Status s)
|
||||
{
|
||||
}
|
||||
|
||||
Status Tick()
|
||||
{
|
||||
if (status != Running)
|
||||
Initialize();
|
||||
virtual void serialize(memstream_t *stream)
|
||||
{
|
||||
uint8_t s = (uint8_t)status;
|
||||
|
||||
status = Update();
|
||||
memstream_write(stream, &s, sizeof(s));
|
||||
}
|
||||
|
||||
if (status != Running)
|
||||
Terminate(status);
|
||||
virtual void unserialize(memstream_t *stream)
|
||||
{
|
||||
uint8_t s;
|
||||
|
||||
return status;
|
||||
}
|
||||
memstream_read(stream, &s, sizeof(s));
|
||||
status = bt::Status(s);
|
||||
}
|
||||
|
||||
Status Tick()
|
||||
{
|
||||
if (status != Running)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
status = Update();
|
||||
|
||||
if (status != Running)
|
||||
{
|
||||
Terminate(status);
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
bool IsSuccess() const
|
||||
{
|
||||
return(status == Success);
|
||||
}
|
||||
|
||||
bool IsFailure() const
|
||||
{
|
||||
return(status == Failure);
|
||||
}
|
||||
|
||||
bool IsRunning() const
|
||||
{
|
||||
return(status == Running);
|
||||
}
|
||||
|
||||
bool IsTerminated() const
|
||||
{
|
||||
return(IsSuccess() || IsFailure());
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
status = Invalid;
|
||||
}
|
||||
|
||||
bool IsSuccess() const {
|
||||
return status == Success;
|
||||
}
|
||||
bool IsFailure() const {
|
||||
return status == Failure;
|
||||
}
|
||||
bool IsRunning() const {
|
||||
return status == Running;
|
||||
}
|
||||
bool IsTerminated() const {
|
||||
return IsSuccess() || IsFailure();
|
||||
}
|
||||
void Reset() {
|
||||
status = Invalid;
|
||||
}
|
||||
protected:
|
||||
Status status;
|
||||
Status status;
|
||||
};
|
||||
|
||||
//using Nodes = std::vector<Node *>;
|
||||
|
||||
}
|
||||
|
@ -4,42 +4,45 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
/*
|
||||
The Selector composite ticks each child node in order.
|
||||
If a child succeeds or runs, the sequence returns the same status.
|
||||
In the next tick, it will try to run each child in order again.
|
||||
If all children fails, only then does the selector fail.
|
||||
* The Selector composite ticks each child node in order.
|
||||
* If a child succeeds or runs, the sequence returns the same status.
|
||||
* In the next tick, it will try to run each child in order again.
|
||||
* If all children fails, only then does the selector fail.
|
||||
*/
|
||||
class Selector : public Composite
|
||||
{
|
||||
public:
|
||||
void Initialize()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
void Initialize()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
Status Update()
|
||||
{
|
||||
if (HasNoChildren())
|
||||
return Success;
|
||||
Status Update()
|
||||
{
|
||||
if (HasNoChildren())
|
||||
{
|
||||
return(Success);
|
||||
}
|
||||
|
||||
// Keep going until a child behavior says it's running.
|
||||
while (1)
|
||||
{
|
||||
bt::Node * child = children.at(index);
|
||||
bt::Status status = child->Tick();
|
||||
// Keep going until a child behavior says it's running.
|
||||
while (1)
|
||||
{
|
||||
bt::Node * child = children.at(index);
|
||||
bt::Status status = child->Tick();
|
||||
|
||||
// If the child succeeds, or keeps running, do the same.
|
||||
if (status != Failure)
|
||||
return status;
|
||||
|
||||
// Hit the end of the array, it didn't end well...
|
||||
if (++index == (signed)children.size())
|
||||
return Failure;
|
||||
}
|
||||
}
|
||||
// If the child succeeds, or keeps running, do the same.
|
||||
if (status != Failure)
|
||||
{
|
||||
return(status);
|
||||
}
|
||||
|
||||
// Hit the end of the array, it didn't end well...
|
||||
if (++index == (signed)children.size())
|
||||
{
|
||||
return(Failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -4,41 +4,45 @@
|
||||
|
||||
namespace bt
|
||||
{
|
||||
|
||||
/*
|
||||
The Sequence composite ticks each child node in order.
|
||||
If a child fails or runs, the sequence returns the same status.
|
||||
In the next tick, it will try to run each child in order again.
|
||||
If all children succeeds, only then does the sequence succeed.
|
||||
* The Sequence composite ticks each child node in order.
|
||||
* If a child fails or runs, the sequence returns the same status.
|
||||
* In the next tick, it will try to run each child in order again.
|
||||
* If all children succeeds, only then does the sequence succeed.
|
||||
*/
|
||||
class Sequence : public Composite
|
||||
{
|
||||
public:
|
||||
void Initialize()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
void Initialize()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
Status Update()
|
||||
{
|
||||
if (HasNoChildren())
|
||||
return Success;
|
||||
Status Update()
|
||||
{
|
||||
if (HasNoChildren())
|
||||
{
|
||||
return(Success);
|
||||
}
|
||||
|
||||
// Keep going until a child behavior says it's running.
|
||||
while (1)
|
||||
{
|
||||
bt::Node * child = children.at(index);
|
||||
bt::Status status = child->Tick();
|
||||
// Keep going until a child behavior says it's running.
|
||||
while (1)
|
||||
{
|
||||
bt::Node * child = children.at(index);
|
||||
bt::Status status = child->Tick();
|
||||
|
||||
// If the child fails, or keeps running, do the same.
|
||||
if (status != Success)
|
||||
return status;
|
||||
// If the child fails, or keeps running, do the same.
|
||||
if (status != Success)
|
||||
{
|
||||
return(status);
|
||||
}
|
||||
|
||||
// Hit the end of the array, job done!
|
||||
if (++index == (signed)children.size())
|
||||
return Success;
|
||||
}
|
||||
}
|
||||
// Hit the end of the array, job done!
|
||||
if (++index == (signed)children.size())
|
||||
{
|
||||
return(Success);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
81
common.hpp
81
common.hpp
@ -7,71 +7,74 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define GAME_NAME "Mr.Boom"
|
||||
#define GAME_VERSION "4.1"
|
||||
#define PATH_MAX_LENGTH 256
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
#define NB_COLORS_PALETTE 256
|
||||
#define nb_dyna 8
|
||||
#define GAME_NAME "Mr.Boom"
|
||||
#define GAME_VERSION "4.1"
|
||||
#define PATH_MAX_LENGTH 256
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
#define NB_COLORS_PALETTE 256
|
||||
#define nb_dyna 8
|
||||
|
||||
class BotTree;
|
||||
extern BotTree* tree[nb_dyna];
|
||||
enum Button {
|
||||
button_b,
|
||||
button_y,
|
||||
button_select,
|
||||
button_start,
|
||||
button_up,
|
||||
button_down,
|
||||
button_left,
|
||||
button_right,
|
||||
button_a,
|
||||
button_x,
|
||||
button_l,
|
||||
button_r,
|
||||
button_error
|
||||
extern BotTree *tree[nb_dyna];
|
||||
enum Button
|
||||
{
|
||||
button_b,
|
||||
button_y,
|
||||
button_select,
|
||||
button_start,
|
||||
button_up,
|
||||
button_down,
|
||||
button_left,
|
||||
button_right,
|
||||
button_a,
|
||||
button_x,
|
||||
button_l,
|
||||
button_r,
|
||||
button_error
|
||||
};
|
||||
|
||||
#define FIRST_RW_VARIABLE replayer_saver
|
||||
#define FIRST_RW_VARIABLE_DB nosetjmp
|
||||
#define NB_DD_VARIABLES_IN_RW_SEGMENT (offsetof(struct Mem,FIRST_RW_VARIABLE_DB)-offsetof(struct Mem,FIRST_RW_VARIABLE))/4
|
||||
#define FIRST_RO_VARIABLE master
|
||||
#define SIZE_RO_SEGMENT offsetof(struct Mem,FIRST_RW_VARIABLE)-offsetof(struct Mem,FIRST_RO_VARIABLE)
|
||||
#define SIZE_SER offsetof(struct Mem,selectorsPointer)-offsetof(struct Mem,FIRST_RW_VARIABLE)
|
||||
#define FIRST_RW_VARIABLE replayer_saver
|
||||
#define FIRST_RW_VARIABLE_DB nosetjmp
|
||||
#define NB_DD_VARIABLES_IN_RW_SEGMENT (offsetof(struct Mem, FIRST_RW_VARIABLE_DB) - offsetof(struct Mem, FIRST_RW_VARIABLE)) / 4
|
||||
#define FIRST_RO_VARIABLE master
|
||||
#define SIZE_RO_SEGMENT offsetof(struct Mem, FIRST_RW_VARIABLE) - offsetof(struct Mem, FIRST_RO_VARIABLE)
|
||||
#define SIZE_SER offsetof(struct Mem, selectorsPointer) - offsetof(struct Mem, FIRST_RW_VARIABLE)
|
||||
bool mrboom_init();
|
||||
void mrboom_deinit(void);
|
||||
void mrboom_update_input(int keyid,int playerNumber,int state,bool isIA);
|
||||
void mrboom_update_input(int keyid, int playerNumber, int state, bool isIA);
|
||||
void mrboom_sound(void);
|
||||
bool mrboom_debug_state_failed();
|
||||
void mrboom_reset_special_keys();
|
||||
void mrboom_tick_ai();
|
||||
void mrboom_deal_with_autofire();
|
||||
bool debugTracesPlayer(int player);
|
||||
|
||||
extern bool cheatMode;
|
||||
#ifdef DEBUG
|
||||
enum BotState { goingNowhere, goingSafe, goingBonus, goingBomb };
|
||||
extern BotState botStates[nb_dyna];
|
||||
extern int walkingToCell[nb_dyna];
|
||||
extern int walkingToCell[nb_dyna];
|
||||
#endif
|
||||
#ifdef __LIBRETRO__
|
||||
#define FPS_RATE 60.0
|
||||
#define SAMPLE_RATE 48000.0f
|
||||
#define FPS_RATE 60.0
|
||||
#define SAMPLE_RATE 48000.0f
|
||||
extern int16_t *frame_sample_buf;
|
||||
extern uint32_t num_samples_per_frame;
|
||||
extern retro_audio_sample_batch_t audio_batch_cb;
|
||||
void audio_callback(void);
|
||||
#define DEFAULT_TRACE_MAX 0
|
||||
|
||||
#define DEFAULT_TRACE_MAX 0
|
||||
#endif
|
||||
#ifdef __LIBSDL2__
|
||||
extern int sdl2_fx_volume;
|
||||
extern int sdl2_fx_volume;
|
||||
extern bool music;
|
||||
#define DEFAULT_SDL2_FX_VOLUME 4
|
||||
#define DEFAULT_TRACE_MAX 1 | DEBUG_MASK_GRIDS
|
||||
#define DEFAULT_SDL2_FX_VOLUME 4
|
||||
#define DEFAULT_TRACE_MAX 1 | DEBUG_MASK_GRIDS
|
||||
#endif
|
||||
#define DEBUG_SDL2 1024
|
||||
#define DEBUG_MASK_BOTTREEDECISIONS 512
|
||||
#define DEBUG_MASK_GRIDS 256
|
||||
#define DEBUG_SDL2 1024
|
||||
#define DEBUG_MASK_BOTTREEDECISIONS 512
|
||||
#define DEBUG_MASK_GRIDS 256
|
||||
extern int traceMask;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
2209
libretro.h
2209
libretro.h
File diff suppressed because it is too large
Load Diff
676
retro.cpp
676
retro.cpp
@ -9,227 +9,235 @@
|
||||
|
||||
static uint32_t *frame_buf;
|
||||
static struct retro_log_callback logging;
|
||||
retro_log_printf_t log_cb;
|
||||
static char retro_save_directory[4096];
|
||||
static char retro_base_directory[4096];
|
||||
retro_log_printf_t log_cb;
|
||||
static char retro_save_directory[4096];
|
||||
static char retro_base_directory[4096];
|
||||
static retro_video_refresh_t video_cb;
|
||||
static retro_audio_sample_t audio_cb;
|
||||
static retro_environment_t environ_cb;
|
||||
static retro_input_poll_t input_poll_cb;
|
||||
static retro_input_state_t input_state_cb;
|
||||
static retro_audio_sample_t audio_cb;
|
||||
static retro_environment_t environ_cb;
|
||||
static retro_input_poll_t input_poll_cb;
|
||||
static retro_input_state_t input_state_cb;
|
||||
|
||||
// Global core options
|
||||
static const struct retro_variable var_mrboom_nomonster = { "mrboom-nomonster", "Monsters; ON|OFF" };
|
||||
static const struct retro_variable var_mrboom_teammode = { "mrboom-teammode", "Team mode; Selfie|Color|Sex" };
|
||||
static const struct retro_variable var_mrboom_autofire = { "mrboom-autofire", "Drop bomb autofire; OFF|ON" };
|
||||
static const struct retro_variable var_mrboom_teammode = { "mrboom-teammode", "Team mode; Selfie|Color|Sex" };
|
||||
static const struct retro_variable var_mrboom_autofire = { "mrboom-autofire", "Drop bomb autofire; OFF|ON" };
|
||||
|
||||
static const struct retro_variable var_empty = { NULL, NULL };
|
||||
|
||||
// joypads
|
||||
|
||||
#define DESC_NUM_PORTS(desc) ((desc)->port_max - (desc)->port_min + 1)
|
||||
#define DESC_NUM_INDICES(desc) ((desc)->index_max - (desc)->index_min + 1)
|
||||
#define DESC_NUM_IDS(desc) ((desc)->id_max - (desc)->id_min + 1)
|
||||
#define DESC_NUM_PORTS(desc) ((desc)->port_max - (desc)->port_min + 1)
|
||||
#define DESC_NUM_INDICES(desc) ((desc)->index_max - (desc)->index_min + 1)
|
||||
#define DESC_NUM_IDS(desc) ((desc)->id_max - (desc)->id_min + 1)
|
||||
|
||||
#define DESC_OFFSET(desc, port, index, id) ( \
|
||||
port * ((desc)->index_max - (desc)->index_min + 1) * ((desc)->id_max - (desc)->id_min + 1) + \
|
||||
index * ((desc)->id_max - (desc)->id_min + 1) + \
|
||||
id \
|
||||
)
|
||||
#define DESC_OFFSET(desc, port, index, id) ( \
|
||||
port * ((desc)->index_max - (desc)->index_min + 1) * ((desc)->id_max - (desc)->id_min + 1) + \
|
||||
index * ((desc)->id_max - (desc)->id_min + 1) + \
|
||||
id \
|
||||
)
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
struct descriptor
|
||||
{
|
||||
int device;
|
||||
int port_min;
|
||||
int port_max;
|
||||
int index_min;
|
||||
int index_max;
|
||||
int id_min;
|
||||
int id_max;
|
||||
uint16_t *value;
|
||||
int device;
|
||||
int port_min;
|
||||
int port_max;
|
||||
int index_min;
|
||||
int index_max;
|
||||
int id_min;
|
||||
int id_max;
|
||||
uint16_t *value;
|
||||
};
|
||||
|
||||
static struct descriptor joypad;
|
||||
|
||||
static struct descriptor *descriptors[] = {
|
||||
&joypad
|
||||
&joypad
|
||||
};
|
||||
|
||||
static void fallback_log(enum retro_log_level level, const char *fmt, ...)
|
||||
{
|
||||
(void)level;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
vfprintf(stderr, fmt, va);
|
||||
va_end(va);
|
||||
(void)level;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
vfprintf(stderr, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void retro_init(void)
|
||||
{
|
||||
int size;
|
||||
unsigned i;
|
||||
struct descriptor *desc = NULL;
|
||||
const char *dir = NULL;
|
||||
int size;
|
||||
unsigned i;
|
||||
struct descriptor *desc = NULL;
|
||||
const char * dir = NULL;
|
||||
|
||||
joypad.device = RETRO_DEVICE_JOYPAD;
|
||||
joypad.port_min = 0;
|
||||
joypad.port_max = 7;
|
||||
joypad.index_min = 0;
|
||||
joypad.index_max = 0;
|
||||
joypad.id_min = RETRO_DEVICE_ID_JOYPAD_B;
|
||||
joypad.id_max = RETRO_DEVICE_ID_JOYPAD_R3;
|
||||
joypad.device = RETRO_DEVICE_JOYPAD;
|
||||
joypad.port_min = 0;
|
||||
joypad.port_max = 7;
|
||||
joypad.index_min = 0;
|
||||
joypad.index_max = 0;
|
||||
joypad.id_min = RETRO_DEVICE_ID_JOYPAD_B;
|
||||
joypad.id_max = RETRO_DEVICE_ID_JOYPAD_R3;
|
||||
|
||||
num_samples_per_frame = SAMPLE_RATE / FPS_RATE;
|
||||
num_samples_per_frame = SAMPLE_RATE / FPS_RATE;
|
||||
|
||||
frame_sample_buf = (int16_t*)memalign_alloc(128, num_samples_per_frame * 2 * sizeof(int16_t));
|
||||
frame_sample_buf = (int16_t *)memalign_alloc(128, num_samples_per_frame * 2 * sizeof(int16_t));
|
||||
|
||||
memset(frame_sample_buf, 0, num_samples_per_frame * 2 * sizeof(int16_t));
|
||||
memset(frame_sample_buf, 0, num_samples_per_frame * 2 * sizeof(int16_t));
|
||||
|
||||
log_cb(RETRO_LOG_DEBUG, "retro_init");
|
||||
log_cb(RETRO_LOG_DEBUG, "retro_init");
|
||||
|
||||
sprintf(retro_base_directory,"/tmp");
|
||||
sprintf(retro_base_directory, "/tmp");
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
|
||||
{
|
||||
if (strlen(dir))
|
||||
snprintf(retro_base_directory, sizeof(retro_base_directory), "%s", dir);
|
||||
}
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
|
||||
{
|
||||
if (strlen(dir))
|
||||
{
|
||||
snprintf(retro_base_directory, sizeof(retro_base_directory), "%s", dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
|
||||
{
|
||||
// If save directory is defined use it, otherwise use system directory
|
||||
if (strlen(dir))
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", dir);
|
||||
else
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", retro_base_directory);
|
||||
}
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
|
||||
{
|
||||
// If save directory is defined use it, otherwise use system directory
|
||||
if (strlen(dir))
|
||||
{
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", retro_base_directory);
|
||||
}
|
||||
}
|
||||
|
||||
frame_buf = (uint32_t *) calloc(WIDTH * HEIGHT, sizeof(uint32_t));
|
||||
frame_buf = (uint32_t *)calloc(WIDTH * HEIGHT, sizeof(uint32_t));
|
||||
|
||||
mrboom_init();
|
||||
mrboom_init();
|
||||
|
||||
/* joypads Allocate descriptor values */
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++) {
|
||||
desc = descriptors[i];
|
||||
size = DESC_NUM_PORTS(desc) * DESC_NUM_INDICES(desc) * DESC_NUM_IDS(desc);
|
||||
descriptors[i]->value = (uint16_t*)calloc(size, sizeof(uint16_t));
|
||||
}
|
||||
/* joypads Allocate descriptor values */
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
|
||||
{
|
||||
desc = descriptors[i];
|
||||
size = DESC_NUM_PORTS(desc) * DESC_NUM_INDICES(desc) * DESC_NUM_IDS(desc);
|
||||
descriptors[i]->value = (uint16_t *)calloc(size, sizeof(uint16_t));
|
||||
}
|
||||
}
|
||||
|
||||
void retro_deinit(void)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned i;
|
||||
|
||||
free(frame_buf);
|
||||
memalign_free(frame_sample_buf);
|
||||
frame_buf = NULL;
|
||||
free(frame_buf);
|
||||
memalign_free(frame_sample_buf);
|
||||
frame_buf = NULL;
|
||||
|
||||
/* Free descriptor values */
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
|
||||
{
|
||||
free(descriptors[i]->value);
|
||||
descriptors[i]->value = NULL;
|
||||
}
|
||||
/* Free descriptor values */
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
|
||||
{
|
||||
free(descriptors[i]->value);
|
||||
descriptors[i]->value = NULL;
|
||||
}
|
||||
|
||||
mrboom_deinit();
|
||||
mrboom_deinit();
|
||||
}
|
||||
|
||||
unsigned retro_api_version(void)
|
||||
{
|
||||
return RETRO_API_VERSION;
|
||||
return(RETRO_API_VERSION);
|
||||
}
|
||||
|
||||
void retro_set_controller_port_device(unsigned port, unsigned device)
|
||||
{
|
||||
log_cb(RETRO_LOG_INFO, "%s: Plugging device %u into port %u.\n", GAME_NAME, device, port);
|
||||
log_cb(RETRO_LOG_INFO, "%s: Plugging device %u into port %u.\n", GAME_NAME, device, port);
|
||||
}
|
||||
|
||||
void retro_get_system_info(struct retro_system_info *info)
|
||||
{
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->library_name = GAME_NAME;
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->library_name = GAME_NAME;
|
||||
#ifdef GIT_VERSION
|
||||
info->library_version = GAME_VERSION GIT_VERSION;
|
||||
info->library_version = GAME_VERSION GIT_VERSION;
|
||||
#else
|
||||
info->library_version = GAME_VERSION;
|
||||
info->library_version = GAME_VERSION;
|
||||
#endif
|
||||
info->need_fullpath = false;
|
||||
info->valid_extensions = NULL;
|
||||
info->need_fullpath = false;
|
||||
info->valid_extensions = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void retro_get_system_av_info(struct retro_system_av_info *info)
|
||||
{
|
||||
float aspect = 16.0f / 9.0f;
|
||||
float aspect = 16.0f / 9.0f;
|
||||
|
||||
float sampling_rate = SAMPLE_RATE;
|
||||
float sampling_rate = SAMPLE_RATE;
|
||||
|
||||
info->timing.fps = FPS_RATE;
|
||||
info->timing.sample_rate = sampling_rate;
|
||||
|
||||
info->geometry.base_width = WIDTH;
|
||||
info->geometry.base_height = HEIGHT;
|
||||
info->geometry.max_width = WIDTH;
|
||||
info->geometry.max_height = HEIGHT;
|
||||
info->geometry.aspect_ratio = aspect;
|
||||
info->timing.fps = FPS_RATE;
|
||||
info->timing.sample_rate = sampling_rate;
|
||||
|
||||
info->geometry.base_width = WIDTH;
|
||||
info->geometry.base_height = HEIGHT;
|
||||
info->geometry.max_width = WIDTH;
|
||||
info->geometry.max_height = HEIGHT;
|
||||
info->geometry.aspect_ratio = aspect;
|
||||
}
|
||||
|
||||
void retro_set_environment(retro_environment_t cb)
|
||||
{
|
||||
environ_cb = cb;
|
||||
bool no_content = true;
|
||||
cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_content);
|
||||
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
|
||||
log_cb = logging.log;
|
||||
else
|
||||
log_cb = fallback_log;
|
||||
std::vector<const retro_variable*> vars_systems;
|
||||
// Add the Global core options
|
||||
vars_systems.push_back(&var_mrboom_teammode);
|
||||
vars_systems.push_back(&var_mrboom_nomonster);
|
||||
vars_systems.push_back(&var_mrboom_autofire);
|
||||
environ_cb = cb;
|
||||
bool no_content = true;
|
||||
cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_content);
|
||||
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
|
||||
{
|
||||
log_cb = logging.log;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_cb = fallback_log;
|
||||
}
|
||||
std::vector <const retro_variable *> vars_systems;
|
||||
// Add the Global core options
|
||||
vars_systems.push_back(&var_mrboom_teammode);
|
||||
vars_systems.push_back(&var_mrboom_nomonster);
|
||||
vars_systems.push_back(&var_mrboom_autofire);
|
||||
|
||||
#define NB_VARS_SYSTEMS 3
|
||||
assert(vars_systems.size()==NB_VARS_SYSTEMS);
|
||||
// Add the System core options
|
||||
int idx_var = 0;
|
||||
struct retro_variable vars[NB_VARS_SYSTEMS + 1]; // + 1 for the empty ending retro_variable
|
||||
for (int i = 0; i < NB_VARS_SYSTEMS; i++, idx_var++)
|
||||
{
|
||||
vars[idx_var] = *vars_systems[i];
|
||||
log_cb(RETRO_LOG_INFO, "retro_variable (SYSTEM) { '%s', '%s' }\n", vars[idx_var].key, vars[idx_var].value);
|
||||
}
|
||||
vars[idx_var] = var_empty;
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
|
||||
#define NB_VARS_SYSTEMS 3
|
||||
assert(vars_systems.size() == NB_VARS_SYSTEMS);
|
||||
// Add the System core options
|
||||
int idx_var = 0;
|
||||
struct retro_variable vars[NB_VARS_SYSTEMS + 1]; // + 1 for the empty ending retro_variable
|
||||
for (int i = 0; i < NB_VARS_SYSTEMS; i++, idx_var++)
|
||||
{
|
||||
vars[idx_var] = *vars_systems[i];
|
||||
log_cb(RETRO_LOG_INFO, "retro_variable (SYSTEM) { '%s', '%s' }\n", vars[idx_var].key, vars[idx_var].value);
|
||||
}
|
||||
vars[idx_var] = var_empty;
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars);
|
||||
}
|
||||
|
||||
void retro_set_audio_sample(retro_audio_sample_t cb)
|
||||
{
|
||||
audio_cb = cb;
|
||||
audio_cb = cb;
|
||||
}
|
||||
|
||||
void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
|
||||
{
|
||||
audio_batch_cb = cb;
|
||||
audio_batch_cb = cb;
|
||||
}
|
||||
|
||||
void retro_set_input_poll(retro_input_poll_t cb)
|
||||
{
|
||||
input_poll_cb = cb;
|
||||
input_poll_cb = cb;
|
||||
}
|
||||
|
||||
void retro_set_input_state(retro_input_state_t cb)
|
||||
{
|
||||
input_state_cb = cb;
|
||||
input_state_cb = cb;
|
||||
}
|
||||
|
||||
void retro_set_video_refresh(retro_video_refresh_t cb)
|
||||
{
|
||||
video_cb = cb;
|
||||
video_cb = cb;
|
||||
}
|
||||
|
||||
void retro_reset(void)
|
||||
@ -238,165 +246,192 @@ void retro_reset(void)
|
||||
|
||||
static void update_input(void)
|
||||
{
|
||||
uint16_t state;
|
||||
int offset;
|
||||
int port;
|
||||
int index;
|
||||
int id;
|
||||
unsigned i;
|
||||
uint16_t state;
|
||||
int offset;
|
||||
int port;
|
||||
int index;
|
||||
int id;
|
||||
unsigned i;
|
||||
|
||||
/* Poll input */
|
||||
input_poll_cb();
|
||||
/* Poll input */
|
||||
input_poll_cb();
|
||||
|
||||
/* Parse descriptors */
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
|
||||
{
|
||||
/* Get current descriptor */
|
||||
struct descriptor *desc = descriptors[i];
|
||||
/* Parse descriptors */
|
||||
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
|
||||
{
|
||||
/* Get current descriptor */
|
||||
struct descriptor *desc = descriptors[i];
|
||||
|
||||
/* Go through range of ports/indices/IDs */
|
||||
for (port = desc->port_min; port <= desc->port_max; port++)
|
||||
for (index = desc->index_min; index <= desc->index_max; index++)
|
||||
for (id = desc->id_min; id <= desc->id_max; id++)
|
||||
{
|
||||
/* Compute offset into array */
|
||||
offset = DESC_OFFSET(desc, port, index, id);
|
||||
/* Go through range of ports/indices/IDs */
|
||||
for (port = desc->port_min; port <= desc->port_max; port++)
|
||||
{
|
||||
for (index = desc->index_min; index <= desc->index_max; index++)
|
||||
{
|
||||
for (id = desc->id_min; id <= desc->id_max; id++)
|
||||
{
|
||||
/* Compute offset into array */
|
||||
offset = DESC_OFFSET(desc, port, index, id);
|
||||
|
||||
/* Get new state */
|
||||
state = input_state_cb(port,
|
||||
desc->device,
|
||||
index,
|
||||
id);
|
||||
/* Update state */
|
||||
if (desc->value[offset] != state) {
|
||||
mrboom_update_input(id,port,state,false);
|
||||
}
|
||||
desc->value[offset] = state;
|
||||
}
|
||||
}
|
||||
/* Get new state */
|
||||
state = input_state_cb(port,
|
||||
desc->device,
|
||||
index,
|
||||
id);
|
||||
/* Update state */
|
||||
if (desc->value[offset] != state)
|
||||
{
|
||||
mrboom_update_input(id, port, state, false);
|
||||
}
|
||||
desc->value[offset] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_vga(uint32_t *buf, unsigned stride)
|
||||
{
|
||||
static uint32_t matrixPalette[NB_COLORS_PALETTE];
|
||||
unsigned x, y;
|
||||
int z = 0;
|
||||
uint32_t *line = buf;
|
||||
static uint32_t matrixPalette[NB_COLORS_PALETTE];
|
||||
unsigned x, y;
|
||||
int z = 0;
|
||||
uint32_t * line = buf;
|
||||
|
||||
do {
|
||||
matrixPalette[z/3]= ((m.vgaPalette[z]*4) << 16) | ((m.vgaPalette[z+1]*4) << 8) | (m.vgaPalette[z+2]*4);
|
||||
z+=3;
|
||||
} while (z!=NB_COLORS_PALETTE*3);
|
||||
do
|
||||
{
|
||||
matrixPalette[z / 3] = ((m.vgaPalette[z] * 4) << 16) | ((m.vgaPalette[z + 1] * 4) << 8) | (m.vgaPalette[z + 2] * 4);
|
||||
z += 3;
|
||||
} while (z != NB_COLORS_PALETTE * 3);
|
||||
|
||||
for (y = 0; y < HEIGHT; y++, line += stride)
|
||||
{
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
{
|
||||
if (y<HEIGHT)
|
||||
line[x] = matrixPalette[m.vgaRam[x+y*WIDTH]];
|
||||
}
|
||||
}
|
||||
for (y = 0; y < HEIGHT; y++, line += stride)
|
||||
{
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
{
|
||||
if (y < HEIGHT)
|
||||
{
|
||||
line[x] = matrixPalette[m.vgaRam[x + y * WIDTH]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void render_checkered(void)
|
||||
{
|
||||
mrboom_sound();
|
||||
|
||||
mrboom_sound();
|
||||
|
||||
/* Try rendering straight into VRAM if we can. */
|
||||
uint32_t *buf = NULL;
|
||||
unsigned stride = 0;
|
||||
struct retro_framebuffer fb = {0};
|
||||
fb.width = WIDTH;
|
||||
fb.height = HEIGHT;
|
||||
fb.access_flags = RETRO_MEMORY_ACCESS_WRITE;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_XRGB8888)
|
||||
{
|
||||
buf = (uint32_t *) fb.data;
|
||||
stride = fb.pitch >> 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = frame_buf;
|
||||
stride = WIDTH;
|
||||
}
|
||||
update_vga(buf,stride);
|
||||
video_cb(buf, WIDTH, HEIGHT, stride << 2);
|
||||
/* Try rendering straight into VRAM if we can. */
|
||||
uint32_t *buf = NULL;
|
||||
unsigned stride = 0;
|
||||
struct retro_framebuffer fb = { 0 };
|
||||
fb.width = WIDTH;
|
||||
fb.height = HEIGHT;
|
||||
fb.access_flags = RETRO_MEMORY_ACCESS_WRITE;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_XRGB8888)
|
||||
{
|
||||
buf = (uint32_t *)fb.data;
|
||||
stride = fb.pitch >> 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = frame_buf;
|
||||
stride = WIDTH;
|
||||
}
|
||||
update_vga(buf, stride);
|
||||
video_cb(buf, WIDTH, HEIGHT, stride << 2);
|
||||
}
|
||||
|
||||
|
||||
static void check_variables(void)
|
||||
{
|
||||
struct retro_variable var = {0};
|
||||
var.key = var_mrboom_nomonster.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "ON") == 0)
|
||||
setNoMonsterMode(false);
|
||||
else
|
||||
setNoMonsterMode(true);
|
||||
}
|
||||
var.key = var_mrboom_autofire.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "ON") == 0)
|
||||
setAutofire(true);
|
||||
else
|
||||
setAutofire(false);
|
||||
}
|
||||
var.key = var_mrboom_teammode.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "Selfie") == 0)
|
||||
setTeamMode(0);
|
||||
else if (strcmp(var.value, "Sex") == 0)
|
||||
setTeamMode(2);
|
||||
else
|
||||
setTeamMode(1);
|
||||
}
|
||||
struct retro_variable var = { 0 };
|
||||
|
||||
var.key = var_mrboom_nomonster.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "ON") == 0)
|
||||
{
|
||||
setNoMonsterMode(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setNoMonsterMode(true);
|
||||
}
|
||||
}
|
||||
var.key = var_mrboom_autofire.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "ON") == 0)
|
||||
{
|
||||
setAutofire(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
setAutofire(false);
|
||||
}
|
||||
}
|
||||
var.key = var_mrboom_teammode.key;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
|
||||
{
|
||||
if (strcmp(var.value, "Selfie") == 0)
|
||||
{
|
||||
setTeamMode(0);
|
||||
}
|
||||
else if (strcmp(var.value, "Sex") == 0)
|
||||
{
|
||||
setTeamMode(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTeamMode(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void retro_run(void)
|
||||
{
|
||||
static int frame=0;
|
||||
int newFrameNumber=frameNumber();
|
||||
frame++;
|
||||
if (frame!=newFrameNumber) {
|
||||
if ((frame) && (newFrameNumber)) {
|
||||
log_error("Network resynched: %d -> %d\n",frame,newFrameNumber);
|
||||
}
|
||||
}
|
||||
frame=newFrameNumber;
|
||||
update_input();
|
||||
mrboom_deal_with_autofire();
|
||||
render_checkered();
|
||||
audio_callback();
|
||||
program();
|
||||
mrboom_reset_special_keys();
|
||||
mrboom_tick_ai();
|
||||
if (m.executionFinished) {
|
||||
log_cb(RETRO_LOG_INFO, "Exit.\n");
|
||||
environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
|
||||
}
|
||||
bool updated = false;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
|
||||
check_variables();
|
||||
}
|
||||
static int frame = 0;
|
||||
int newFrameNumber = frameNumber();
|
||||
|
||||
frame++;
|
||||
if (frame != newFrameNumber)
|
||||
{
|
||||
if ((frame) && (newFrameNumber))
|
||||
{
|
||||
log_error("Network resynched: %d -> %d\n", frame, newFrameNumber);
|
||||
}
|
||||
}
|
||||
frame = newFrameNumber;
|
||||
update_input();
|
||||
mrboom_deal_with_autofire();
|
||||
render_checkered();
|
||||
audio_callback();
|
||||
program();
|
||||
mrboom_reset_special_keys();
|
||||
mrboom_tick_ai();
|
||||
if (m.executionFinished)
|
||||
{
|
||||
log_cb(RETRO_LOG_INFO, "Exit.\n");
|
||||
environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
|
||||
}
|
||||
bool updated = false;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
|
||||
{
|
||||
check_variables();
|
||||
}
|
||||
}
|
||||
|
||||
bool retro_load_game(const struct retro_game_info *info)
|
||||
{
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
{
|
||||
log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
|
||||
return false;
|
||||
}
|
||||
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
|
||||
|
||||
check_variables();
|
||||
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
|
||||
{
|
||||
log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
(void)info;
|
||||
return true;
|
||||
check_variables();
|
||||
|
||||
(void)info;
|
||||
return(true);
|
||||
}
|
||||
|
||||
void retro_unload_game(void)
|
||||
@ -405,77 +440,88 @@ void retro_unload_game(void)
|
||||
|
||||
unsigned retro_get_region(void)
|
||||
{
|
||||
return RETRO_REGION_NTSC;
|
||||
return(RETRO_REGION_NTSC);
|
||||
}
|
||||
|
||||
bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
|
||||
{
|
||||
return retro_load_game(NULL);
|
||||
return(retro_load_game(NULL));
|
||||
}
|
||||
|
||||
#define HARDCODED_RETRO_SERIALIZE_SIZE SIZE_SER+13*8
|
||||
#define HARDCODED_RETRO_SERIALIZE_SIZE SIZE_SER + 13 * 8
|
||||
size_t retro_serialize_size(void)
|
||||
{
|
||||
size_t result=HARDCODED_RETRO_SERIALIZE_SIZE;
|
||||
assert(tree[0]!=NULL);
|
||||
if (tree[0]!=NULL) {
|
||||
result=(SIZE_SER+tree[0]->serialize_size()*nb_dyna);
|
||||
assert(HARDCODED_RETRO_SERIALIZE_SIZE==result);
|
||||
} else {
|
||||
log_error("retro_serialize_size returning hardcoded value.\n");
|
||||
}
|
||||
assert(SIZE_MEM_MAX>result);
|
||||
return result;
|
||||
size_t result = HARDCODED_RETRO_SERIALIZE_SIZE;
|
||||
|
||||
assert(tree[0] != NULL);
|
||||
if (tree[0] != NULL)
|
||||
{
|
||||
result = (SIZE_SER + tree[0]->serialize_size() * nb_dyna);
|
||||
assert(HARDCODED_RETRO_SERIALIZE_SIZE == result);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("retro_serialize_size returning hardcoded value.\n");
|
||||
}
|
||||
assert(SIZE_MEM_MAX > result);
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool retro_serialize(void *data_, size_t size)
|
||||
{
|
||||
memcpy(data_, &m.FIRST_RW_VARIABLE, SIZE_SER);
|
||||
if (is_little_endian()==false) {
|
||||
fixBigEndian(data_);
|
||||
}
|
||||
size_t offset=SIZE_SER;
|
||||
for (int i=0; i<nb_dyna; i++) {
|
||||
assert(tree[i]!=NULL);
|
||||
tree[i]->serialize(((char *) data_)+offset);
|
||||
offset+=tree[i]->serialize_size();
|
||||
}
|
||||
return true;
|
||||
memcpy(data_, &m.FIRST_RW_VARIABLE, SIZE_SER);
|
||||
if (is_little_endian() == false)
|
||||
{
|
||||
fixBigEndian(data_);
|
||||
}
|
||||
size_t offset = SIZE_SER;
|
||||
for (int i = 0; i < nb_dyna; i++)
|
||||
{
|
||||
assert(tree[i] != NULL);
|
||||
tree[i]->serialize(((char *)data_) + offset);
|
||||
offset += tree[i]->serialize_size();
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool retro_unserialize(const void *data_, size_t size)
|
||||
{
|
||||
if (size!=retro_serialize_size()) {
|
||||
log_error("retro_unserialize error %d/%d\n",size,retro_serialize_size());
|
||||
return false;
|
||||
}
|
||||
if (is_little_endian()==false) {
|
||||
char dataTmp[SIZE_MEM_MAX];
|
||||
memcpy(dataTmp,data_, SIZE_SER);
|
||||
fixBigEndian(dataTmp);
|
||||
memcpy(&m.FIRST_RW_VARIABLE, dataTmp, SIZE_SER);
|
||||
} else {
|
||||
memcpy(&m.FIRST_RW_VARIABLE, data_, SIZE_SER);
|
||||
}
|
||||
size_t offset=SIZE_SER;
|
||||
for (int i=0; i<nb_dyna; i++) {
|
||||
assert(tree[i]!=NULL);
|
||||
tree[i]->unserialize(((char *) data_)+offset);
|
||||
offset+=tree[i]->serialize_size();
|
||||
}
|
||||
return true;
|
||||
if (size != retro_serialize_size())
|
||||
{
|
||||
log_error("retro_unserialize error %d/%d\n", size, retro_serialize_size());
|
||||
return(false);
|
||||
}
|
||||
if (is_little_endian() == false)
|
||||
{
|
||||
char dataTmp[SIZE_MEM_MAX];
|
||||
memcpy(dataTmp, data_, SIZE_SER);
|
||||
fixBigEndian(dataTmp);
|
||||
memcpy(&m.FIRST_RW_VARIABLE, dataTmp, SIZE_SER);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&m.FIRST_RW_VARIABLE, data_, SIZE_SER);
|
||||
}
|
||||
size_t offset = SIZE_SER;
|
||||
for (int i = 0; i < nb_dyna; i++)
|
||||
{
|
||||
assert(tree[i] != NULL);
|
||||
tree[i]->unserialize(((char *)data_) + offset);
|
||||
offset += tree[i]->serialize_size();
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
void *retro_get_memory_data(unsigned id)
|
||||
{
|
||||
(void)id;
|
||||
return NULL;
|
||||
(void)id;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
size_t retro_get_memory_size(unsigned id)
|
||||
{
|
||||
(void)id;
|
||||
return 0;
|
||||
(void)id;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void retro_cheat_reset(void)
|
||||
@ -484,14 +530,16 @@ void retro_cheat_reset(void)
|
||||
|
||||
void retro_cheat_set(unsigned index, bool enabled, const char *code)
|
||||
{
|
||||
(void)index;
|
||||
(void)enabled;
|
||||
(void)code;
|
||||
(void)index;
|
||||
(void)enabled;
|
||||
(void)code;
|
||||
}
|
||||
|
||||
void show_message(const char * message) {
|
||||
struct retro_message msg;
|
||||
msg.msg = message;
|
||||
msg.frames = 80;
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
|
||||
void show_message(const char *message)
|
||||
{
|
||||
struct retro_message msg;
|
||||
|
||||
msg.msg = message;
|
||||
msg.frames = 80;
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void *)&msg);
|
||||
}
|
||||
|
@ -3,12 +3,13 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define SIZE_MEM_MAX 30000
|
||||
#define SIZE_MEM_MAX 30000
|
||||
void update_vga(uint32_t *buf, unsigned stride);
|
||||
void show_message(const char * show_message);
|
||||
void show_message(const char *show_message);
|
||||
size_t retro_serialize_size(void);
|
||||
bool retro_serialize(void *data_, size_t size);
|
||||
bool retro_unserialize(const void *data_, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
137239
retro_data.h
137239
retro_data.h
File diff suppressed because it is too large
Load Diff
2033
sdl2/sdl2.cpp
2033
sdl2/sdl2.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user