📄 board_initialise.cpp
字号:
// ============================================================================
// Game board initialisation
//
// (c) 2003 Ken Reed
//
// This is free software. You can redistribute it and/or modify it under the
// terms of the GNU General Public License version 2 as published by the Free
// Software Foundation.
// ============================================================================
#include "stdafx.h"
#include "board.h"
#include "point.h"
#include "random.h"
#include <assert.h>
#include <math.h>
#include <vector>
using namespace std;
struct Location {
Point position;
int player;
};
namespace {
vector<Location> base_positions;
}
// ============================================================================
// Set up the game board
// ============================================================================
void Board::initialise(bool is_exploring, bool hide_vectors,
bool do_attrition, bool do_disrupt)
{
hidden = hide_vectors;
exploring = is_exploring;
attrition = do_attrition;
disrupt = do_disrupt;
for (int j = 0; j < board_y_size; j++) {
for (int i = 0; i < board_x_size; i++) {
cells[j][i].reset(exploring);
}
}
setup_terrain();
}
// ============================================================================
// Create terrain
// ============================================================================
void Board::setup_terrain ()
{
int peak_count (irandom(15, 30));
double range (250);
for (int p = 0; p < peak_count; p++) {
Point peak;
peak.x = irandom(0, size.x);
peak.y = irandom(0, size.y);
int height (irandom(max_elevation / 4, max_elevation));
bool sea (false);
double dice (random(0, 100));
if (dice > 80)sea = true;
for (int j = 0; j < board_y_size; j++) {
for (int i = 0; i < board_x_size; i++) {
Cell * cell = (& cells[j][i]);
Point this_cell (cell->get_centre());
double peak_distance (this_cell.distance_to(peak));
if (peak_distance < range) {
double increment (height / range);
double elevation (height - (increment * peak_distance));
if (sea) {
cell->elevation -= elevation;
if (cell->elevation < -max_elevation) {
cell->elevation = -max_elevation;
}
}
else {
cell->elevation += elevation;
if (cell->elevation > max_elevation) {
cell->elevation = max_elevation;
}
}
}
}
}
}
}
// ============================================================================
// Set up bases ensuring a minium distance separates each base.
// ============================================================================
void Board::setup_player(int player, int number_of_bases, bool group_bases)
{
int bi(-1);
int bj(-1);
base_positions.clear();
for (int base = 0; base < number_of_bases; base++) {
if (base == 0) {
bi = -1;
bj = -1;
}
Point position (get_base(player, bi, bj));
Cell * cell = (get_cell(position));
assert(cell != 0);
cell->player = player;
cell->type = Base;
cell->strength = 100;
if (group_bases && (base == 0)) {
bi = cell->i;
bj = cell->j;
}
Location new_base;
new_base.position = position;
new_base.player = player;
base_positions.push_back(new_base);
}
}
// ============================================================================
// Get a base position
// ============================================================================
Point Board::get_base(int player, int bi, int bj)
{
for (int i = 5000; i > 0; i--) {
Cell * cell = (random_cell(bi, bj));
if (cell->elevation < 0) continue;
Point new_position(cell->get_centre());
if (player == 0) return new_position;
bool too_close(false);
vector<Location>::iterator p;
for (p = base_positions.begin(); p != base_positions.end(); p++) {
Location base (*p);
if (base.player != player) {
Point position (base.position);
int distance (position.distance_to(new_position));
if (distance < 200) {
too_close = true;
}
}
}
if (! too_close) return new_position;
}
Exception e("Could not position base");
RAISE(e);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -