![]() |
Kukatz 3D
0.1
Török Attila szakdolgozata
|
00001 /* 00002 * aiplayer.cpp - Kukatz 3D 00003 * Copyright (c) 2011, 2012 - TÖRÖK Attila (torokati44@gmail.com) 00004 * 00005 * This software is provided 'as-is', without any express or implied 00006 * warranty. In no event will the authors be held liable for any damages 00007 * arising from the use of this software. 00008 * 00009 * Permission is granted to anyone to use this software for any purpose, 00010 * including commercial applications, and to alter it and redistribute it 00011 * freely, subject to the following restrictions: 00012 * 00013 * 1. The origin of this software must not be misrepresented; you must not 00014 * claim that you wrote the original software. If you use this software 00015 * in a product, an acknowledgment in the product documentation would be 00016 * appreciated but is not required. 00017 * 00018 * 2. Altered source versions must be plainly marked as such, and must not be 00019 * misrepresented as being the original software. 00020 * 00021 * 3. This notice may not be removed or altered from any source 00022 * distribution. 00023 */ 00024 00025 #include "aiplayer.hpp" 00026 00027 #include <vector> 00028 #include <iostream> 00029 00030 #include <SFML/System/Randomizer.hpp> 00031 #include "game.hpp" 00032 #include "edible.hpp" 00033 #include "misc.hpp" 00034 00035 AIPlayer::AIPlayer(const sf::Unicode::Text& n, float s, Kukac* k, Game* g): 00036 Player(n, k), game_ptr(g), moves_since_last_turn(0), moves_left_to_target(0), 00037 skill(s) 00038 { 00039 if (sf::Randomizer::Random(0.0f, 1.0f) <= skill) 00040 { 00041 find_target(); 00042 } 00043 else 00044 { 00045 random_target(); 00046 } 00047 } 00048 00049 void AIPlayer::find_target() 00050 { 00051 Edible* target_edible = game_ptr->get_closest_edible( 00052 kukac_ptr->head->pos + kukac_ptr->direction); 00053 00054 if (target_edible) 00055 { 00056 target = game_ptr->get_closest_edible( 00057 kukac_ptr->head->pos + kukac_ptr->direction)->pos; 00058 } 00059 else 00060 { 00061 target = kukac_ptr->head->pos + kukac_ptr->direction + kukac_ptr->direction; 00062 } 00063 00064 sf::Vector3i diff = kukac_ptr->head->pos - target; 00065 moves_left_to_target = (std::abs(diff.x) + std::abs(diff.y) + std::abs(diff.z)) * 2; 00066 } 00067 00068 void AIPlayer::random_target() 00069 { 00070 target = game_ptr->get_random_empty_pos(); 00071 sf::Vector3i diff = kukac_ptr->head->pos - target; 00072 moves_left_to_target = (std::abs(diff.x) + std::abs(diff.y) + std::abs(diff.z)) * 2; 00073 } 00074 00075 void AIPlayer::update(float dt) 00076 { 00077 kukac_ptr->update(dt); 00078 00079 if (kukac_ptr->did_move()) 00080 { 00081 --moves_left_to_target; 00082 if (!moves_left_to_target) 00083 { 00084 if (sf::Randomizer::Random(0.0f, 1.0f) <= skill) 00085 { 00086 find_target(); 00087 } 00088 else 00089 { 00090 random_target(); 00091 } 00092 } 00093 00094 ++moves_since_last_turn; 00095 00096 if ((float)moves_since_last_turn < (2.5f * (1.0f - skill))) 00097 { 00098 return; 00099 } 00100 00101 const sf::Vector3i& pos = kukac_ptr->head->pos; 00102 const sf::Vector3i& dir = kukac_ptr->direction; 00103 00104 sf::Vector3i headpos_2 = pos + dir; // will be 00105 00106 if (kukac_ptr->did_reverse() || (headpos_2 == target) || (pos == target) 00107 //|| (kukac_ptr->grid(target + sf::Vector3i(20, 20, 20)).type != GridCell::EDIBLE) 00108 || !(kukac_ptr->can_move_to(target))) 00109 { 00110 if (sf::Randomizer::Random(0.0f, 1.0f) <= skill) 00111 { 00112 find_target(); 00113 } 00114 else 00115 { 00116 random_target(); 00117 } 00118 } 00119 00120 const sf::Vector3i& up = kukac_ptr->upward; 00121 sf::Vector3i right = crossprod(dir, up); 00122 00123 struct 00124 { 00125 char way; 00126 unsigned int dist; 00127 } turns[5]; 00128 00129 turns[0].way = 0; 00130 unsigned int dist_fw = 00131 turns[0].dist = step_dist(target, headpos_2 + dir); 00132 00133 turns[1].way = 1; 00134 turns[1].dist = step_dist(target, headpos_2 + up); 00135 00136 turns[2].way = 2; 00137 turns[2].dist = step_dist(target, headpos_2 - right); 00138 00139 turns[3].way = 3; 00140 turns[3].dist = step_dist(target, headpos_2 - up); 00141 00142 turns[4].way = 4; 00143 turns[4].dist = step_dist(target, headpos_2 + right); 00144 00145 00146 // bubble sort FTW!!! :D 00147 00148 char temp_w; 00149 unsigned int temp_dist; 00150 00151 for (size_t i = 0; i < 4; ++i) 00152 { 00153 for (size_t j = i + 1; j < 5; ++j) 00154 { 00155 if (turns[j].dist < turns[i].dist) 00156 { 00157 temp_w = turns[j].way; 00158 turns[j].way = turns[i].way; 00159 turns[i].way = temp_w; 00160 00161 temp_dist = turns[j].dist; 00162 turns[j].dist = turns[i].dist; 00163 turns[i].dist = temp_dist; 00164 } 00165 } 00166 } 00167 00168 00169 for (size_t i = 0; i < 5; ++i) 00170 { 00171 if ((turns[i].dist >= dist_fw) && kukac_ptr->can_move_to(headpos_2 + dir)) 00172 { 00173 return; 00174 } 00175 else 00176 { 00177 switch (turns[i].way) 00178 { 00179 case 0: 00180 { 00181 if (kukac_ptr->can_move_to(headpos_2 + dir)) 00182 { 00183 // no need to turn 00184 return; 00185 } 00186 } 00187 break; 00188 case 1: 00189 { 00190 if (kukac_ptr->can_move_to(headpos_2 + up)) 00191 { 00192 kukac_ptr->turn_up(); 00193 moves_since_last_turn = 0; 00194 return; 00195 } 00196 } 00197 break; 00198 case 2: 00199 { 00200 if (kukac_ptr->can_move_to(headpos_2 - right)) 00201 { 00202 kukac_ptr->turn_left(); 00203 moves_since_last_turn = 0; 00204 return; 00205 } 00206 } 00207 break; 00208 case 3: 00209 { 00210 if (kukac_ptr->can_move_to(headpos_2 - up)) 00211 { 00212 kukac_ptr->turn_down(); 00213 moves_since_last_turn = 0; 00214 return; 00215 } 00216 } 00217 break; 00218 case 4: 00219 { 00220 if (kukac_ptr->can_move_to(headpos_2 + right)) 00221 { 00222 kukac_ptr->turn_right(); 00223 moves_since_last_turn = 0; 00224 return; 00225 } 00226 } 00227 break; 00228 } 00229 } 00230 } 00231 } 00232 } 00233 00234 AIPlayer::~AIPlayer() 00235 { 00236 00237 }