Kukatz 3D  0.1
Török Attila szakdolgozata
projects/Kukatz 3D/src/aiplayer.cpp
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 }
 Összes Osztályok