我正在为C学校做一个项目,基本上我需要做的是创建一个代理网格(人类,僵尸或没有)并随机选择我手动控制或“AI”控制的。基本上人类需要从僵尸和僵尸运行必须追逐人类感染它们,游戏结束时没有人类离开。
问题是,在每次转弯之前应该随机选择谁先玩,为此我需要洗牌代理(不接触网格,因为代理位置保持不变,唯一改变的是他们在我应该用来挑选谁先玩的阵列。
我在洗牌时遇到了一些麻烦,因为我打电话给这个功能,在我洗牌后我打印他们的ID。它只给了我很多0,介于一些随机数字之间,如3,6,10等等,只有几个。
以下是代码:
主文件:
/
这是随机播放功能
#include "showworld.h"
#include "example.h"
#include "shuffle.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/** Horizontal world size. */
#define WORLD_X 20
/** Vertical world size. */
#define WORLD_Y 20
/**
* Structure defining agent properties.
*
* @note This is an example which will probably not work in a fully functional
* game. Students should develop their own implementation of
* ::get_agent_info_at() and agent/world data structures.
* */
typedef struct {
AGENT_TYPE type; /**< Agent type. */
unsigned char playable; /**< Is agent playable? */
unsigned short id; /**< Agent ID. */
} AGENT;
/**
* Structure defining world properties.
*
* @note This is an example which will probably not work in a fully functional
* game. Students should develop their own implementation of
* ::get_agent_info_at() and agent/world data structures.
* */
typedef struct {
AGENT *grid; /**< World is a grid composed of agents. */
unsigned int xsize; /**< Horizontal world size. */
unsigned int ysize; /**< Vertical world size. */
} WORLD;
/* This function is an implementation of the definition provided by the
* ::get_agent_info_at() function pointer. It only works for AGENT and WORLD
* example structures defined in this file. */
unsigned int example_get_ag_info(void *world, unsigned int x, unsigned int y);
int main() {
/* An instance of a WORLD structure. */
WORLD my_world;
/* An instance of a SHOWWORLD world display. */
SHOWWORLD *sw = NULL;
/* A by-dimensional array of agents, representing agents in a grid. */
AGENT agent_grid[WORLD_X][WORLD_Y];
/* Number of agents created so far. */
unsigned int nagents = 0;
/* Initialize world display. */
sw = showworld_new(WORLD_X, WORLD_Y, example_get_ag_info);
/* Initialize random number generator. */
srand(time(NULL));
/* **************************************************************** */
/* Cycle through all cells in grid and randomly place agents in it. */
/* **************************************************************** */
for (int i = 0; i < WORLD_X; ++i) {
for (int j = 0; j < WORLD_Y; ++j) {
/* Possible agent in grid. By default we assume there is none. */
AGENT ag = {None, 0, 0};
/* Obtain a probability between 0 and 99. */
unsigned char probability = rand() % 100;
/* There is 10% probability of creating an agent. */
if (probability < 10) {
/* If we got here, an agent will be placed at (i,j). */
/* Randomly define agent type. */
ag.type = (rand() % 2 == 0) ? Human : Zombie;
/* Give 10% probablity of agent being playable by user. */
ag.playable = (rand() % 10 == 0);
/* Assign agent ID and then increment number of agents so
far. */
ag.id = nagents++;
}
/* Assign possible agent to grid at (i,j). */
agent_grid[i][j] = ag;
}
}
/* ******************************* */
/* Populate the my_world variable. */
/* ******************************* */
/* A bidimensional array of agents can be interpreted as a pointer to
agents. */
my_world.grid = (AGENT *) agent_grid;
/* World size is defined by constants in this example. */
my_world.xsize = WORLD_X;
my_world.ysize = WORLD_Y;
/* ********************************************************************* */
/* Show world using the simple_show_world() function. This function can */
/* be used in the first part of the project. */
/* ********************************************************************* */
showworld_update(sw, &my_world);
shuffle(my_world.grid, nagents);
/* Before finishing, ask user to press ENTER. */
printf("Press ENTER to continue...");
getchar();
/* Destroy world display. */
showworld_destroy(sw);
/* Bye. */
return 0;
}
/**
* This function is an implementation of the ::get_agent_info_at() function
* definition. It only works for ::AGENT and ::WORLD structures defined in this
* example.
*
* It basically receives a pointer to a ::WORLD structure, obtains the AGENT
* structure in the given coordinates, and returns the agent information in a
* bit-packed `unsigned int`.
*
* @note This is an example which will probably not work in a fully functional
* game. Students should develop their own implementation of
* ::get_agent_info_at() and agent/world data structures.
*
* @param w Generic pointer to object representing the simulation world.
* @param x Horizontal coordinate of the simulation world from where to fetch
* the agent information.
* @param y Vertical coordinate of the simulation world from where to fetch
* the agent information.
* @return An integer containing bit-packed information about an agent, as
* follows: bits 0-1 (agent type), bit 2 (is agent playable), bits 3-18 (agent
* ID). Bits 19-31 are available for student-defined agent extensions.
* */
unsigned int example_get_ag_info(void *w, unsigned int x, unsigned int y) {
/* The agent information to return. */
unsigned int ag_info = 0;
/* Convert generic pointer to world to a WORLD object. */
WORLD *my_world = (WORLD *) w;
/* Check if the given (x,y) coordinates are within bounds of the world. */
if ((x >= my_world->xsize) || (y >= my_world->ysize)) {
/* If we got here, then the coordinates are off bounds. As such we will
report that the requested agent is of unknown type. No need to
specify agent ID or playable status, since the agent is unknown. */
ag_info = Unknown;
} else {
/* Given coordinates are within bounds, let's get and pack the request
agent information. */
/* Obtain agent at specified coordinates. */
AGENT ag = my_world->grid[x * my_world->xsize + y];
/* Is there an agent at (x,y)? */
if (ag.type == None) {
/* If there is no agent at the (x,y) coordinates, set agent type to
None. No need to specify agent ID or playable status, since
there is no agent here. */
ag_info = None;
} else {
/* If we get here it's because there is an agent at (x,y). Bit-pack
all the agent information as specified by the get_agent_info_at
function pointer definition. */
ag_info = (ag.id << 3) | (ag.playable << 2) | ag.type;
}
}
/* Return the requested agent information. */
return ag_info;
}
这是showworld文件:
#include "example.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void shuffle(AGENT *agents, unsigned int nagents) {
printf("%s\n\n", "------------- Shuffling agents ----------------");
unsigned int i=0;
unsigned int j=0;
AGENT temp;
srand(time(NULL));
for (i = nagents - 1; i > 0; i--) {
j = (rand() % i);
temp = agents[i];
agents[i] = agents[j];
agents[j] = temp;
}
for (i = 0; i < nagents; i++) {
printf("\n\t%d", agents[i].id);
}
答案 0 :(得分:1)
将所有代码剥离到相关代码:
AGENT agent_grid[WORLD_X][WORLD_Y];
int nagents = populate_grid(agent_grid, WORLD_X, WORLD_Y, 10);
shuffle(agent_grid, nagents);
在这里,我已移除my_world
以关注网格,并创建网格初始化函数,而不是内联初始化。假设的初始化函数int populate_grid(AGENT *grid, int rows, int cols, int percent)
使用代理(以及其他类型为“NONE”的AGENT
个对象)填充网格样本。然后它返回创建的样本大小。
然后,使用对shuffle
的调用精确地对网格进行混洗,AGENT
采用agent_grid
个对象并对其进行随机播放。
这个叙述中的问题显而易见吗? nagents
不是shuffle
所期望的大小为WORLD_X * WORLD_Y
的数组。它是一个大小为<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
的二维数组。在实践中,这意味着你正在改组前40个(左右)网格槽,而另一个360不受影响;我们可以预期,这些网格插槽中有90%是空的,这似乎与您描述的结果相符(&#34;很多,很多0&#34;)。
答案 1 :(得分:0)
这是很多代码,但我要寻找的第一件事是边界错误。确保您的数组索引是一致的,并且不要访问数组中有效范围之外的项目。
下一个问题是你的洗牌。 Jeff Atwood wrote an entire blog about it.
祝你好运!