⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 board_initialise.cpp

📁 通用网络游戏开发框架
💻 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 + -