示例#1
0
/**
 * Move nb_pawns of the player p from the cell src_cell to the cell dst_cell
 *
 * Check if dst and src are neighbours
 * error if not
 * check dst owner
 * if owner == p or null
 * 		move pawns
 * else
 * 		fight
 * if not draw (no move)
 * 		remove pawns from src.
 *
 * return move result (nofight, draw, win, lost)
 */
short player_move_to_cell(s_player *p, uint16_t nb_pawns, struct s_cell *src_cell, struct s_cell *dst_cell)
{
	short result;

	if (nb_pawns > p->nb_pawns)
		return PLAYER_ERROR_MOVE_NOT_ENOUGH_PAWNS;
	else if (nb_pawns >= src_cell->nb_pawns)
		return PLAYER_ERROR_MOVE_ALL_PAWNS;

	if (!cell_are_neighbours(src_cell, dst_cell)) {
		return PLAYER_ERROR_MOVE_CELLS_NOT_NEIGHBOURS;
	}

	if (dst_cell->owner != NULL && dst_cell->owner->id != p->id) {
		// fight
		result = _fight(nb_pawns, dst_cell);
	}
	else {
		if (dst_cell->owner == NULL) {
			dst_cell->owner = p;
			p->nb_cells++;
		}
		dst_cell->nb_pawns = (uint16_t) (dst_cell->nb_pawns + nb_pawns);
		result = NO_FIGHT;
	}

	if (result != FIGHT_DRAW) {
		src_cell->nb_pawns = (uint16_t) (src_cell->nb_pawns - nb_pawns);

		if (result == FIGHT_LOST) {
			p->nb_pawns = (uint16_t) (p->nb_pawns - nb_pawns);
		}
		else if (result == FIGHT_WON) {
			// update opponent pawns and cells number
			dst_cell->owner->nb_pawns = (uint16_t) (dst_cell->owner->nb_pawns - dst_cell->nb_pawns);
			dst_cell->owner->nb_cells--;

			// update cell owner
			dst_cell->owner = p;
			dst_cell->nb_pawns = nb_pawns;
			p->nb_cells = (uint8_t) (p->nb_cells + 1);
		}
	}

	return result;
}
示例#2
0
/**
   Primary state machine for ninja fight game handles exchange of packets and setting up game
   between the two players
*/
static void _doNinja(NinjaState *state, NinjaPacket *packet) {
  uint32_t endTime = 0;

  //Init the game state
  state->p1Idle1 = getBitmapMetadata(NINJA_P1_IDLE1_address);
  state->p2Idle1 = getBitmapMetadata(NINJA_P2_IDLE1_address);
  state->p1Idle2 = getBitmapMetadata(NINJA_P1_IDLE2_address);
  state->p2Idle2 = getBitmapMetadata(NINJA_P2_IDLE2_address);

  state->p1Punch1 = getBitmapMetadata(NINJA_P1_PUNCH1_address);
  state->p2Punch1 = getBitmapMetadata(NINJA_P2_PUNCH1_address);
  state->p1Punch2 = getBitmapMetadata(NINJA_P1_PUNCH2_address);
  state->p2Punch2 = getBitmapMetadata(NINJA_P2_PUNCH2_address);

  state->p1Kick1 = getBitmapMetadata(NINJA_P1_KICK1_address);
  state->p2Kick1 = getBitmapMetadata(NINJA_P2_KICK1_address);
  state->p1Kick2 = getBitmapMetadata(NINJA_P1_KICK2_address);
  state->p2Kick2 = getBitmapMetadata(NINJA_P2_KICK2_address);

  state->p1Shield1 = getBitmapMetadata(NINJA_P1_SHIELD1_address);
  state->p2Shield1 = getBitmapMetadata(NINJA_P2_SHIELD1_address);
  state->p1Shield2 = getBitmapMetadata(NINJA_P1_SHIELD2_address);
  state->p2Shield2 = getBitmapMetadata(NINJA_P2_SHIELD2_address);

  state->p1Dead = getBitmapMetadata(NINJA_P1_DEAD_address);
  state->p2Dead = getBitmapMetadata(NINJA_P2_DEAD_address);

  state->troll = getBitmapMetadata(NINJA_DT_address);

  state->punch = getBitmapMetadata(NINJA_PUNCH_address);
  state->kick = getBitmapMetadata(NINJA_KICK_address);
  state->shield = getBitmapMetadata(NINJA_SHIELD_address);
  state->up = getBitmapMetadata(NINJA_UP_address);
  state->down = getBitmapMetadata(NINJA_DOWN_address);
  state->right = getBitmapMetadata(NINJA_RIGHT_address);
  state->state = STATE_SELECT_MOVE;
  state->round = 1;
  state->p1Score = 0;
  state->p2Score = 0;

  while (state->p1Score < 2 && state->p2Score < 2) {
    if (state->state == STATE_SELECT_MOVE) {
      state->lastACK = -1;
      //Set p2Move to -1 *before* _getPlayerMove (which could change it!)
      state->p2Move = -1; //other player move
      state->p1Move = _getPlayerMove(state, packet);


      endTime = rtMillis() + 20000;
      bool ackRecv = false;
      bool moveRecv = false;

      //Wait for a bit sending and receiving until we're synced with other player
      while (state->lastACK != TYPE_MOVE || state->p2Move < 0) {

        //Show a dialog to the player
        char wait[32];
        sprintf(wait, "Waiting for\nplayer %d", (endTime - rtMillis()) / 1000);
        statusDialog(wait);
        safeDisplay();

        //Keep sending until an ACK is received
        if (state->lastACK != TYPE_MOVE) {
          //Fill out the rest of the packet
          packet->type = TYPE_MOVE;
          packet->data = state->p1Move;
          packet->round = state->round;
          ANXRFSend(packet, NINJA_PACKET_SIZE);
        }

        //Delay and do some ticking (400ms)
        for (uint8_t i = 0; i < 16; i++) {
          deepSleep(25);
          tick();
          //Process any data that comes in
          _handlePackets(state, packet);
        }

        //give up on other player
        if (rtMillis() > endTime) {
          state->state = STATE_ABORT;
          break;
        }
      }

      //Bump them over to fight
      if (state->state != STATE_ABORT) state->state = STATE_FIGHT;

    } else if (state->state == STATE_FIGHT) {
      _fight(state, packet);
      state->state = STATE_SELECT_MOVE;
      state->round++;
    } else if (state->state == STATE_ABORT) {
      break;
    }

    deepSleep(200);
    tick();
  }

  _gameOver(state);
  enablePopups();
}