File indexing completed on 2024-04-28 04:04:38

0001 /*
0002     This file is part of the game 'KTron'
0003 
0004     SPDX-FileCopyrightText: 1998-2000 Matthias Kiefer <matthias.kiefer@gmx.de>
0005     SPDX-FileCopyrightText: 2005 Benjamin C. Meyer <ben at meyerhome dot net>
0006     SPDX-FileCopyrightText: 2008-2009 Stas Verberkt <legolas at legolasweb dot nl>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 
0010 */
0011   
0012 #include "intelligence.h"
0013 
0014 #include "tron.h"
0015 #include "settings.h"
0016 
0017 #include <KGameDifficulty>
0018 
0019 Intelligence::Intelligence()
0020     : m_random(QRandomGenerator::global()->generate())
0021 {
0022     m_lookForward = 15;
0023 }
0024 
0025 void Intelligence::referenceTron(Tron *t)
0026 {
0027     m_tron = t;
0028 }
0029 
0030 //
0031 // Settings
0032 //
0033 
0034 /** retrieves the opponentSkill */
0035 int Intelligence::opponentSkill() {
0036     switch (KGameDifficulty::globalLevel()) {
0037         case KGameDifficultyLevel::VeryEasy:
0038             return 1;
0039         default:
0040         case KGameDifficultyLevel::Easy:
0041             return 1;
0042         case KGameDifficultyLevel::Medium:
0043             return 2;
0044         case KGameDifficultyLevel::Hard:
0045             return 3;
0046         case KGameDifficultyLevel::VeryHard:
0047             return 3;
0048     }
0049 }
0050 
0051 //
0052 // Algorithm helper function
0053 //
0054 
0055 void Intelligence::changeDirection(int playerNr,int dis_right,int dis_left)
0056 {
0057    PlayerDirections::Direction currentDir = m_tron->getPlayer(playerNr)->getDirection();
0058    PlayerDirections::Direction sides[2];
0059    sides[0] = PlayerDirections::None;
0060    sides[1] = PlayerDirections::None;
0061    
0062    switch (currentDir)
0063    {
0064         case PlayerDirections::Left:
0065             //turns to either side
0066             sides[0] = PlayerDirections::Down;
0067             sides[1] = PlayerDirections::Up;
0068             break;
0069         case PlayerDirections::Right:
0070             sides[0] = PlayerDirections::Up;
0071             sides[1] = PlayerDirections::Down;
0072             break;
0073         case PlayerDirections::Up:
0074             sides[0] = PlayerDirections::Left;
0075             sides[1] = PlayerDirections::Right;
0076             break;
0077         case PlayerDirections::Down:
0078             sides[0] = PlayerDirections::Right;
0079             sides[1] = PlayerDirections::Left;
0080             break;
0081         default:
0082         break;
0083 
0084     }
0085 
0086    if(!(dis_left == 1 && dis_right == 1))
0087    {
0088             // change direction
0089             if (m_random.bounded(100) <= (100*dis_left)/(dis_left+dis_right))
0090             {
0091                 if (dis_left != 1)
0092                     // turn to the left
0093                     m_tron->getPlayer(playerNr)->setDirection(sides[0]);
0094                 else
0095                 // turn to the right
0096                     m_tron->getPlayer(playerNr)->setDirection(sides[1]);
0097             }
0098             else
0099             {
0100                     if (dis_right != 1)
0101                         // turn to the right
0102                         m_tron->getPlayer(playerNr)->setDirection(sides[1]);
0103                     else
0104                         // turn to the left
0105                         m_tron->getPlayer(playerNr)->setDirection(sides[0]);
0106           }
0107     }
0108 }
0109 
0110 // This part is partly ported from
0111 // xtron-1.1 by Rhett D. Jacobs <rhett@hotel.canberra.edu.au>
0112 void Intelligence::think(int playerNr)
0113 {
0114     if (opponentSkill() != 1)
0115     {
0116         int opponent=(playerNr==1)? 0 : 1;
0117 
0118         // determines left and right side
0119         PlayerDirections::Direction sides[2];
0120         sides[0] = PlayerDirections::None;
0121         sides[1] = PlayerDirections::None;
0122         // increments for moving to the different sides
0123         int flags[6]={0,0,0,0,0,0};
0124         int index[2];
0125         // distances to barrier
0126         int dis_forward,  dis_left, dis_right;
0127 
0128         dis_forward = dis_left = dis_right = 1;
0129 
0130         switch (m_tron->getPlayer(playerNr)->getDirection())
0131         {
0132             case PlayerDirections::Left:
0133                 //forward flags
0134                 flags[0] = -1;
0135                 flags[1] = 0;
0136 
0137                 //left flags
0138                 flags[2] = 0;
0139                 flags[3] = 1;
0140 
0141                 // right flags
0142                 flags[4] = 0;
0143                 flags[5] = -1;
0144 
0145                 //turns to either side
0146                 sides[0] = PlayerDirections::Down;
0147                 sides[1] = PlayerDirections::Up;
0148                 break;
0149             case PlayerDirections::Right:
0150                 flags[0] = 1;
0151                 flags[1] = 0;
0152                 flags[2] = 0;
0153                 flags[3] = -1;
0154                 flags[4] = 0;
0155                 flags[5] = 1;
0156                 sides[0] = PlayerDirections::Up;
0157                 sides[1] = PlayerDirections::Down;
0158                 break;
0159             case PlayerDirections::Up:
0160                 flags[0] = 0;
0161                 flags[1] = -1;
0162                 flags[2] = -1;
0163                 flags[3] = 0;
0164                 flags[4] = 1;
0165                 flags[5] = 0;
0166                 sides[0] = PlayerDirections::Left;
0167                 sides[1] = PlayerDirections::Right;
0168                 break;
0169             case PlayerDirections::Down:
0170                 flags[0] = 0;
0171                 flags[1] = 1;
0172                 flags[2] = 1;
0173                 flags[3] = 0;
0174                 flags[4] = -1;
0175                 flags[5] = 0;
0176                 sides[0] = PlayerDirections::Right;
0177                 sides[1] = PlayerDirections::Left;
0178                 break;
0179             default:
0180                 break;
0181         }
0182 
0183         // check forward
0184         index[0] = m_tron->getPlayer(playerNr)->getX()+flags[0];
0185         index[1] = m_tron->getPlayer(playerNr)->getY()+flags[1];
0186         while (index[0] < m_tron->getPlayField()->getWidth() && index[0] >= 0 && index[1] < m_tron->getPlayField()->getHeight() && index[1] >= 0 && m_tron->getPlayField()->getObjectAt(index[0], index[1])->getObjectType() == ObjectType::Object)
0187         {
0188             dis_forward++;
0189             index[0] += flags[0];
0190             index[1] += flags[1];
0191         }
0192 
0193         // check left
0194         index[0] = m_tron->getPlayer(playerNr)->getX()+flags[2];
0195         index[1] = m_tron->getPlayer(playerNr)->getY()+flags[3];
0196         while (index[0] < m_tron->getPlayField()->getWidth() && index[0] >= 0 && index[1] < m_tron->getPlayField()->getHeight() && index[1] >= 0 && m_tron->getPlayField()->getObjectAt(index[0], index[1])->getObjectType() == ObjectType::Object)
0197         {
0198             dis_left++;
0199             index[0] += flags[2];
0200             index[1] += flags[3];
0201         }
0202 
0203         // check right
0204         index[0] = m_tron->getPlayer(playerNr)->getX()+flags[4];
0205         index[1] = m_tron->getPlayer(playerNr)->getY()+flags[5];
0206         while (index[0] < m_tron->getPlayField()->getWidth() && index[0] >= 0 && index[1] <  m_tron->getPlayField()->getHeight() && index[1] >= 0 && m_tron->getPlayField()->getObjectAt(index[0], index[1])->getObjectType() == ObjectType::Object)
0207         {
0208             dis_right++;
0209             index[0] += flags[4];
0210             index[1] += flags[5];
0211         }
0212 
0213         // distances to opponent
0214         int hor_dis=0; // negative is opponent to the right
0215         int vert_dis=0; // negative is opponent to the bottom
0216         hor_dis = m_tron->getPlayer(playerNr)->getX() - m_tron->getPlayer(opponent)->getX();
0217         vert_dis = m_tron->getPlayer(playerNr)->getY() - m_tron->getPlayer(opponent)->getY();
0218 
0219         int opForwardDis=0; // negative is to the back
0220         int opSideDis=0;  // negative is to the left
0221         bool opMovesOppositeDir=false;
0222         bool opMovesSameDir=false;
0223         bool opMovesRight=false;
0224         bool opMovesLeft=false;
0225 
0226         switch (m_tron->getPlayer(playerNr)->getDirection())
0227         {
0228             case PlayerDirections::Up:
0229                 opForwardDis=vert_dis;
0230                 opSideDis=-hor_dis;
0231                 if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Down)
0232                     opMovesOppositeDir=true;
0233                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Up)
0234                     opMovesSameDir=true;
0235                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Left)
0236                     opMovesLeft=true;
0237                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Right)
0238                     opMovesRight=true;
0239                 break;
0240             case PlayerDirections::Down:
0241                 opForwardDis=-vert_dis;
0242                 opSideDis=hor_dis;
0243                 if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Up)
0244                     opMovesOppositeDir=true;
0245                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Down)
0246                     opMovesSameDir=true;
0247                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Left)
0248                     opMovesRight=true;
0249                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Right)
0250                     opMovesLeft=true;
0251                 break;
0252             case PlayerDirections::Left:
0253                 opForwardDis=hor_dis;
0254                 opSideDis=vert_dis;
0255                 if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Right)
0256                     opMovesOppositeDir=true;
0257                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Left)
0258                     opMovesSameDir=true;
0259                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Down)
0260                     opMovesLeft=true;
0261                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Up)
0262                     opMovesRight=true;
0263                 break;
0264             case PlayerDirections::Right:
0265                 opForwardDis=-hor_dis;
0266                 opSideDis=-vert_dis;
0267                 if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Left)
0268                     opMovesOppositeDir=true;
0269                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Right)
0270                     opMovesSameDir=true;
0271                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Up)
0272                     opMovesLeft=true;
0273                 else if(m_tron->getPlayer(opponent)->getDirection()==PlayerDirections::Down)
0274                     opMovesRight=true;
0275                 break;
0276             default:
0277                 break;
0278         }
0279 
0280         int doPercentage = 100;
0281         switch(opponentSkill())
0282         {
0283             case 1:
0284                 // Never reached
0285                 break;
0286             case 2:
0287                 doPercentage=5;
0288                 break;
0289             case 3:
0290                 doPercentage=90;
0291                 break;
0292         }
0293 
0294         // if opponent moves the opposite direction as we
0295         if(opMovesOppositeDir)
0296         {
0297             // if opponent is in front
0298             if(opForwardDis>0)
0299             {
0300                 // opponent is to the right and we have the chance to block the way
0301                 if(opSideDis>0 && opSideDis < opForwardDis && opSideDis < dis_right && opForwardDis < m_lookForward)
0302                 {
0303                     if (m_random.bounded(100) <= doPercentage || dis_forward==1)
0304                         m_tron->getPlayer(playerNr)->setDirection(sides[1]); // turn right
0305                 }
0306                 // opponent is to the left and we have the chance to block the way
0307                 else if(opSideDis<0 && -opSideDis < opForwardDis && -opSideDis < dis_left && opForwardDis < m_lookForward)
0308                 {
0309                     if (m_random.bounded(100) <= doPercentage || dis_forward==1)
0310                         m_tron->getPlayer(playerNr)->setDirection(sides[0]); // turn left
0311                 }
0312                 // if we can do nothing, go forward
0313                 else if(dis_forward < m_lookForward)
0314                 {
0315                     dis_forward = 100 - 100/dis_forward;
0316 
0317                     if(!(dis_left == 1 && dis_right == 1))
0318                         if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0319                             changeDirection(playerNr,dis_right,dis_left);
0320                 }
0321             }
0322             // opponent is in back of us and moves away: do nothing
0323             else if(dis_forward < m_lookForward)
0324             {
0325                 dis_forward = 100 - 100/dis_forward;
0326 
0327                 if(!(dis_left == 1 && dis_right == 1))
0328                     if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0329                             changeDirection(playerNr,dis_right,dis_left);
0330             }
0331         } // end  if(opMovesOppositeDir)
0332         else if(opMovesSameDir)
0333         {
0334             // if opponent is to the back
0335             if(opForwardDis < 0)
0336             {
0337                     // opponent is to the right and we have the chance to block the way
0338                 if(opSideDis>0 && opSideDis < -opForwardDis && opSideDis < dis_right)
0339                 {
0340                     if (m_random.bounded(100) <= doPercentage || dis_forward==1)
0341                         m_tron->getPlayer(playerNr)->setDirection(sides[1]); // turn right
0342                 }
0343                 // opponent is to the left and we have the chance to block the way
0344                 else if(opSideDis<0 && -opSideDis < -opForwardDis && -opSideDis < dis_left)
0345                 {
0346                     if (m_random.bounded(100) <= doPercentage || dis_forward==1)
0347                         m_tron->getPlayer(playerNr)->setDirection(sides[0]); // turn left
0348                 }
0349                 // if we can do nothing, go forward
0350                 else if(dis_forward < m_lookForward)
0351                 {
0352                     dis_forward = 100 - 100/dis_forward;
0353 
0354                         if(!(dis_left == 1 && dis_right == 1))
0355                             if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0356                                 changeDirection(playerNr,dis_right,dis_left);
0357                 }
0358             }
0359             // opponent is in front of us and moves away
0360             else if(dis_forward < m_lookForward)
0361             {
0362                 dis_forward = 100 - 100/dis_forward;
0363 
0364                     if(!(dis_left == 1 && dis_right == 1))
0365                         if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0366                             changeDirection(playerNr,dis_right,dis_left);
0367             }
0368         } // end if(opMovesSameDir)
0369         else if(opMovesRight)
0370         {
0371             // opponent is in front of us
0372             if(opForwardDis>0)
0373             {
0374                 // opponent is to the left
0375                 if(opSideDis < 0 && -opSideDis < opForwardDis && -opSideDis < dis_left)
0376                 {
0377                     if(opForwardDis < m_lookForward && dis_left > m_lookForward)
0378                     {
0379                         if (m_random.bounded(100) <= doPercentage/2 || dis_forward==1)
0380                             changeDirection(playerNr,dis_right,dis_left);
0381                     }
0382                     else if(dis_forward < m_lookForward)
0383                     {
0384                         dis_forward = 100 - 100/dis_forward;
0385 
0386                             if(!(dis_left == 1 && dis_right == 1))
0387                                 if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0388                                     changeDirection(playerNr,dis_right,dis_left);
0389                     }
0390                 }
0391                 // op is to the right and moves away, but maybe we can block him
0392                 else if(opSideDis>=0 && opSideDis < dis_right)
0393                 {
0394                     if(opForwardDis < m_lookForward && dis_right > m_lookForward)
0395                     {
0396                         if (m_random.bounded(100) <= doPercentage/2 || dis_forward==1)
0397                             m_tron->getPlayer(playerNr)->setDirection(sides[1]); // turn right
0398                     }
0399                     else if(dis_forward < m_lookForward)
0400                     {
0401                         dis_forward = 100 - 100/dis_forward;
0402 
0403                             if(!(dis_left == 1 && dis_right == 1))
0404                                 if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0405                                     changeDirection(playerNr,dis_right,dis_left);
0406                     }
0407                 }
0408                 else if(dis_forward < m_lookForward)
0409                 {
0410                     dis_forward = 100 - 100/dis_forward;
0411 
0412                         if(!(dis_left == 1 && dis_right == 1))
0413                             if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0414                                 changeDirection(playerNr,dis_right,dis_left);
0415                 }
0416             }
0417             // opponent is in the back of us
0418             else
0419             {
0420                 // opponent is right from us and we already blocked him
0421                 if(opSideDis>0 && opForwardDis < m_lookForward && opSideDis < dis_right)
0422                 {
0423                     if (m_random.bounded(100) <= doPercentage/2 || dis_forward==1)
0424                         changeDirection(playerNr,dis_right,dis_left);
0425                 }
0426                 else if(dis_forward < m_lookForward)
0427                 {
0428                     dis_forward = 100 - 100/dis_forward;
0429 
0430                         if(!(dis_left == 1 && dis_right == 1))
0431                             if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0432                                 changeDirection(playerNr,dis_right,dis_left);
0433                 }
0434             }
0435         } // end if(opMovesRight)
0436         else if(opMovesLeft)
0437         {
0438             // opponent is in front of us
0439             if(opForwardDis>0)
0440             {
0441                 // opponent is to the right, moves towards us and could block us
0442                 if(opSideDis > 0 && opSideDis < opForwardDis && opSideDis < dis_right)
0443                 {
0444                     if(opForwardDis < m_lookForward && dis_right > m_lookForward)
0445                     {
0446                         if (m_random.bounded(100) <= doPercentage/2 || dis_forward==1)
0447                             changeDirection(playerNr,dis_right,dis_left);
0448                     }
0449                     else if(dis_forward < m_lookForward)
0450                     {
0451                         dis_forward = 100 - 100/dis_forward;
0452 
0453                         if(!(dis_left == 1 && dis_right == 1))
0454                             if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0455                                 changeDirection(playerNr,dis_right,dis_left);
0456                     }
0457                 }
0458                 // op is to the left and moves away, but maybe we can block him
0459                 else if(opSideDis<=0 && opSideDis < dis_left)
0460                 {
0461                     if(opForwardDis < m_lookForward && dis_left > m_lookForward)
0462                     {
0463                         if (m_random.bounded(100) <= doPercentage/2 || dis_forward==1)
0464                             m_tron->getPlayer(playerNr)->setDirection(sides[0]); // m_turn left
0465                         }
0466                     else if(dis_forward < m_lookForward)
0467                     {
0468                         dis_forward = 100 - 100/dis_forward;
0469 
0470                         if(!(dis_left == 1 && dis_right == 1))
0471                             if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0472                                 changeDirection(playerNr,dis_right,dis_left);
0473                     }
0474 
0475                 }
0476                 else if(dis_forward < m_lookForward)
0477                 {
0478                     dis_forward = 100 - 100/dis_forward;
0479 
0480                     if(!(dis_left == 1 && dis_right == 1))
0481                         if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0482                             changeDirection(playerNr,dis_right,dis_left);
0483                 }
0484             }
0485             // opponent is in the back of us
0486             else //if(opForwardDis<=0)
0487             {
0488                 // opponent is left from us and we already blocked him
0489                 if(opSideDis<0 && opForwardDis < m_lookForward && -opSideDis < dis_left)
0490                 {
0491                     if (m_random.bounded(100) <= doPercentage/2 || dis_forward==1)
0492                         changeDirection(playerNr,dis_right,dis_left);
0493                 }
0494                 else if(dis_forward < m_lookForward)
0495                 {
0496                     dis_forward = 100 - 100/dis_forward;
0497 
0498                     if(!(dis_left == 1 && dis_right == 1))
0499                         if (m_random.bounded(100) >= dis_forward || dis_forward == 1)
0500                             changeDirection(playerNr,dis_right,dis_left);
0501                 }
0502             }
0503         } // end if(opMovesLeft)
0504 
0505     }
0506     // This part is completely ported from
0507     // xtron-1.1 by Rhett D. Jacobs <rhett@hotel.canberra.edu.au>
0508     else // Settings::skill() == Settings::EnumSkill::Easy
0509     {
0510         PlayerDirections::Direction sides[2];
0511         sides[0] = PlayerDirections::None;
0512         sides[1] = PlayerDirections::None;
0513         int flags[6] = {0,0,0,0,0,0};
0514         int index[2];
0515         int dis_forward,  dis_left, dis_right;
0516 
0517         dis_forward = dis_left = dis_right = 1;
0518 
0519         switch (m_tron->getPlayer(playerNr)->getDirection()) {
0520             case PlayerDirections::Left:
0521                 //forward flags
0522                 flags[0] = -1;
0523                 flags[1] = 0;
0524                 //left flags
0525                 flags[2] = 0;
0526                 flags[3] = 1;
0527                 // right flags
0528                 flags[4] = 0;
0529                 flags[5] = -1;
0530                 //turns to either side
0531                 sides[0] = PlayerDirections::Down;
0532                 sides[1] = PlayerDirections::Up;
0533                 break;
0534             case PlayerDirections::Right:
0535                 flags[0] = 1;
0536                 flags[1] = 0;
0537                 flags[2] = 0;
0538                 flags[3] = -1;
0539                 flags[4] = 0;
0540                 flags[5] = 1;
0541                 sides[0] = PlayerDirections::Up;
0542                 sides[1] = PlayerDirections::Down;
0543                 break;
0544             case PlayerDirections::Up:
0545                 flags[0] = 0;
0546                 flags[1] = -1;
0547                 flags[2] = -1;
0548                 flags[3] = 0;
0549                 flags[4] = 1;
0550                 flags[5] = 0;
0551                 sides[0] = PlayerDirections::Left;
0552                 sides[1] = PlayerDirections::Right;
0553                 break;
0554             case PlayerDirections::Down:
0555                 flags[0] = 0;
0556                 flags[1] = 1;
0557                 flags[2] = 1;
0558                 flags[3] = 0;
0559                 flags[4] = -1;
0560                 flags[5] = 0;
0561                 sides[0] = PlayerDirections::Right;
0562                 sides[1] = PlayerDirections::Left;
0563                 break;
0564             default:
0565                 break;
0566         }
0567 
0568         // check forward
0569         index[0] = m_tron->getPlayer(playerNr)->getX() + flags[0];
0570         index[1] = m_tron->getPlayer(playerNr)->getY() + flags[1];
0571         while (index[0] < m_tron->getPlayField()->getWidth() && index[0] >= 0 && index[1] < m_tron->getPlayField()->getHeight() && index[1] >= 0 && m_tron->getPlayField()->getObjectAt(index[0], index[1])->getObjectType() == ObjectType::Object) {
0572             dis_forward++;
0573             index[0] += flags[0];
0574             index[1] += flags[1];
0575         }
0576 
0577         if (dis_forward < m_lookForward)
0578         {
0579             dis_forward = 100 - 100 / dis_forward;
0580 
0581             // check left
0582             index[0] = m_tron->getPlayer(playerNr)->getX() + flags[2];
0583             index[1] = m_tron->getPlayer(playerNr)->getY() + flags[3];
0584             while (index[0] < m_tron->getPlayField()->getWidth() && index[0] >= 0 && index[1] < m_tron->getPlayField()->getHeight() && index[1] >= 0 && m_tron->getPlayField()->getObjectAt(index[0], index[1])->getObjectType() == ObjectType::Object) {
0585                 dis_left++;
0586                 index[0] += flags[2];
0587                 index[1] += flags[3];
0588             }
0589 
0590             // check right
0591             index[0] = m_tron->getPlayer(playerNr)->getX() + flags[4];
0592             index[1] = m_tron->getPlayer(playerNr)->getY() + flags[5];
0593             while (index[0] < m_tron->getPlayField()->getWidth() && index[0] >= 0 && index[1] <  m_tron->getPlayField()->getHeight() && index[1] >= 0 && m_tron->getPlayField()->getObjectAt(index[0], index[1])->getObjectType() == ObjectType::Object) {
0594                 dis_right++;
0595                 index[0] += flags[4];
0596                 index[1] += flags[5];
0597             }
0598             if(!(dis_left == 1 && dis_right == 1)) {
0599                 if (m_random.bounded(100) >= dis_forward || dis_forward == 0) {
0600                     // change direction
0601                     if (m_random.bounded(100) <= (100*dis_left)/(dis_left+dis_right)) {
0602                         if (dis_left != 1)
0603                             // turn to the left
0604                             m_tron->getPlayer(playerNr)->setDirection(sides[0]);
0605                         else
0606                             // turn to the right
0607                             m_tron->getPlayer(playerNr)->setDirection(sides[1]);
0608                     }
0609                     else {
0610                         if (dis_right != 1)
0611                             // turn to the right
0612                             m_tron->getPlayer(playerNr)->setDirection(sides[1]);
0613                         else
0614                             // turn to the left
0615                             m_tron->getPlayer(playerNr)->setDirection(sides[0]);
0616                     }
0617                 }
0618             }
0619         }
0620     }
0621 }
0622