Giter Club home page Giter Club logo

dass-ass-2's People

Contributors

ashmitchamoli avatar bharatsahlot avatar kyrylo-shyvam avatar vanshg1729 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

dass-ass-2's Issues

Barbarians don't change target after destroying a wall

Barbarians choose the same wall as the new target after they destroy a Townhall wall. The result of this is that all the Barbarians don't move and are stuck when their target wall is destroyed.

The reason for this is that we don't set self.death property of wall to be True when a wall is destroyed unlike other buildings

if(self.health <= 0):
self.color = Back.LIGHTGREEN_EX + " " + Style.RESET_ALL

Fix:
Set the self.death property to be True :

        if(self.health <= 0):
            self.color = Back.LIGHTGREEN_EX + " " + Style.RESET_ALL
            self.death = True

Unused abstraction

Buildings like cannon, townhall etc. inherit from the Building class, but this abstraction is not used properly. The aim was to have a static list of all buildings and all its base types for easy querying.

dass-ass-2/src/game.py

Lines 81 to 84 in 407bae3

Hut.hutsList = hutsList
Canon.canonsList = canonsList
Wall.wallsList = wallsList
Barbarians.barbariansList = barbariansList

for i in range(len(Hut.hutsList)):

Code smell: Unexploited encapsulation, duplicated code

Suggested refractor

  • Base abstract entity class, which has init, render(colorArray, idArray) and tick() function
  • Game class should support querying active entities by their type

excessive use of literals

In many places all over the code, lines like this exist

colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.YELLOW + " " + Style.RESET_ALL
elif(self.health > 5):
for i in range(self.rows):
for j in range(self.columns):
colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.LIGHTYELLOW_EX + " " + Style.RESET_ALL
elif(self.health > 3):
for i in range(self.rows):
for j in range(self.columns):
colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.LIGHTRED_EX + " " + Style.RESET_ALL
else:
self.death = True
for i in range(self.rows):
for j in range(self.columns):
colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.LIGHTBLACK_EX + " " + Style.RESET_ALL

The code assumes height and width, instead it should be using values rows and columns.

This issue is the single place for all instances like this.

Code smell: Excessive use of literals

Duplicated code in Townhall render function

There is a lot of duplicated code with just the color changed for each health level in the Townhall class render function

def render(self,colorArray,idArray):
if(self.health>7):
for i in range(self.rows):
for j in range(self.columns):
colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.YELLOW + " " + Style.RESET_ALL
elif(self.health > 5):
for i in range(self.rows):
for j in range(self.columns):
colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.LIGHTYELLOW_EX + " " + Style.RESET_ALL
elif(self.health > 3):
for i in range(self.rows):
for j in range(self.columns):
colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.LIGHTRED_EX + " " + Style.RESET_ALL
else:
self.death = True
for i in range(self.rows):
for j in range(self.columns):
colorArray[int(40/2)-1+i][int(80/2)-1+j]= Back.LIGHTBLACK_EX + " " + Style.RESET_ALL

Suggested Refactor:

  • Make a new function which takes the color as input and marks the colorarray for Townhall to that color

Duplicate renderX functions in game.py

Code smell: Duplicate code

def renderHuts():
for i in range(len(Hut.hutsList)):
COC.colorArray=Hut.hutsList[i].render(COC.colorArray)
COC.idArray = Hut.hutsList[i].idUpdate(COC.idArray)
def renderCanons():
for i in range(len(canonsList)):
COC.colorArray=canonsList[i].render(COC.colorArray)
COC.idArray = canonsList[i].idUpdate(COC.idArray)
def renderWalls():
for i in range(len(Wall.wallsList)):
COC.colorArray=Wall.wallsList[i].render(COC.colorArray)
COC.idArray = Wall.wallsList[i].idUpdate(COC.idArray)
def renderBarbarians():
for i in range(len(Barbarians.barbariansList)):
COC.colorArray=Barbarians.barbariansList[i].render(COC.colorArray)
COC.idArray = Barbarians.barbariansList[i].idUpdate(COC.idArray)

Suggested refractor

  • One function which takes a list as input, or,
  • Base class for objects that can be rendered, then we keep just one list for all active objects and render them

git workflow

  • do a fork
  • add this repo as upstream using git remote add upstream [email protected]:Kyrylo-Shyvam/dass-ass-2.git
  • do git pull --rebase upstream master
  • work in master/feature branch
  • do git push origin branch
  • squash(in case many commits) merge PR yourself if small or wait for review
  • after merging do git pull --rebase upstream master because the history will be different

Do only meaningful commits, dont make a commit after every change. If you do then squash them in one.

Terminal settings are not reset after game exits

The following lines modify the terminal to enable raw mode. But the game doesn't reset the settings.

dass-ass-2/src/input.py

Lines 10 to 19 in 407bae3

def __call__(self):
"""Defining __call__."""
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch

Fix: keep the old_settings and set them when exiting.

Mysterious name for the Game Class

The game class only prints the colors filled with other classes. It does nothing else. All the other functionality is in game.py.

Code Smell: Lazy class/freeloader and Mysterious name

Suggested Refractor

  • Rename this class to something like Renderer or,
  • Move actual game logic to this class, making the game.py just create an instance of Game and call its play() or run() function

Broken Rendering

  • King sometimes is rendered as two blocks at different positions instead of one long rectangle.
  • Size of the map changes after some time.
  • Weird rendering of right boundaries.
  • Moving king also moves other objects

Fix: I think the screen isn't cleared properly before rendering. We should first investigate that, and then investigate individual classes. We can also make a class which contains methods for filling a specified area on the console with a specified color. So the rendering code is at one place only.

Related: #7 #8 #12

King movement broken after touching boundaries

When king touches any boundary, then it wont be able to move in the direction opposite to the boundary. Lets say the king is touching the left boundary, then it wont be able to move right. Similar for boundaries in all direction. Touching any corner will disable movement all together.

Fix: Read and fix kings movement code.

Ambiguous function definition

A method called spawn is imported on line 2:

from distutils.spawn import spawn

But this method is defined again on line 115:
def spawn(key):

Also, this function has a lot of duplicate code which can easily be fixed.

dass-ass-2/old-code/game.py

Lines 116 to 130 in 9860e82

if(key == 'z'):
barbarian = Barbarians(38,22)
COC.colorArray = barbarian.render(COC.colorArray)
COC.idArray = barbarian.idUpdate(COC.idArray)
Barbarians.barbariansList.append(barbarian)
if(key == 'c'):
barbarian = Barbarians(17,65)
COC.colorArray = barbarian.render(COC.colorArray)
COC.idArray = barbarian.idUpdate(COC.idArray)
Barbarians.barbariansList.append(barbarian)
if(key == 'v'):
barbarian = Barbarians(35,65)
COC.colorArray = barbarian.render(COC.colorArray)
COC.idArray = barbarian.idUpdate(COC.idArray)
Barbarians.barbariansList.append(barbarian)

Code Smell: ambiguous definition and Repetitive code.
Suggestion: Delete the unused import and remove repetitions.

Pressing 'h' key crashes the game

healStart function is invoked when h key is pressed:

dass-ass-2/old-code/game.py

Lines 229 to 231 in 21d7c31

if(key == 'h'):
healTime = time.time()
healStart()

The following code is run inside healStart which crashes the game:

dass-ass-2/old-code/game.py

Lines 147 to 150 in 21d7c31

def healStart():
COC.color = Back.LIGHTYELLOW_EX + " " + Style.RESET_ALL
Townhall.health = (3/2)*Townhall.health # see issue 6, 10

The reason for the crash is that Townhall has no attribute health which we are trying to access

Fix:
Change Townhall to townhall in the above code because Townhall is the class while townhall is an instance of that class with health property

Large conditional block and repetitive code

Inside move method in barbarians.py.

def move(self,idArray):
if(self.target!=None):
if(self.coordinates[0]<self.target.coordinates[0]):
if(idArray[self.coordinates[0]+1][self.coordinates[1]]==0 or idArray[self.coordinates[0]+1][self.coordinates[1]]==9): # see issue 10
self.coordinates[0]+=self.velocity
elif(self.coordinates[0]>self.target.coordinates[0]):
if(idArray[self.coordinates[0]-1][self.coordinates[1]]==0 or idArray[self.coordinates[0]-1][self.coordinates[1]]==9):
self.coordinates[0]-=self.velocity
elif(self.coordinates[1]<self.target.coordinates[1]):
if(idArray[self.coordinates[0]][self.coordinates[1]+1]==0 or idArray[self.coordinates[0]][self.coordinates[1]+1]==9):
self.coordinates[1]+=self.velocity
elif(self.coordinates[1]>self.target.coordinates[1]):
if(idArray[self.coordinates[0]][self.coordinates[1]-1]==0 or idArray[self.coordinates[0]][self.coordinates[1]-1]==9):
self.coordinates[1]-=self.velocity
if(abs(self.coordinates[0]-self.target.coordinates[0])<=1 and abs(self.coordinates[1]-self.target.coordinates[1])<=1):
self.target.health-=2
if(self.target.health<=0):
self.occupied = False
self.target = None

Code Smell: Conditional complexity and repetitive code.

Suggested Refactoring:

  1. Remove the large code block inside the if statement and keep and if statement at the top with a return inside.
if(self.target == None):
   return idArray
  1. Use a for loop to iterate through all the possible movements instead of repetitive conditional code.

many branches and long lines in kingclass

if(self.coordinates[1]>1 and self.coordinates[1]<79 and self.coordinates[0]> 1 and self.coordinates[0] < 39):
if(COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1]!=0 or COC.idArray[self.coordinates[0]-2][self.coordinates[1]]!=0):
if(COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1]==7 or COC.idArray[self.coordinates[0]-2][self.coordinates[1]]==7):
length = len(wallsList)
for i in range(length):
Wall = wallsList[i]
if(Wall.coordinates[0]==self.coordinates[0]-2 and Wall.coordinates[1]==self.coordinates[1]-1 and Wall.health!=0):
print(1000)
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1] = 0
if(Wall.coordinates[0]==self.coordinates[0]-2 and Wall.coordinates[1] == self.coordinates[1] and Wall.health!=0):
print(1000)
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]-2][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1]==2 or COC.idArray[self.coordinates[0]-2][self.coordinates[1]]==2):
length = len(hutsList)
for i in range(length):
Hut = hutsList[i]
if(Hut.coordinates[0]==self.coordinates[0]-2 and Hut.coordinates[1]==self.coordinates[1]-1 and Hut.health!=0):
Hut.health -= 1
if(Hut.coordinates[0]==self.coordinates[0]-2 and Hut.coordinates[1] == self.coordinates[1] and Hut.health!=0):
Hut.health -= 1
if(Hut.health == 0):
COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1] = 0
COC.idArray[self.coordinates[0]-2][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1]==3 or COC.idArray[self.coordinates[0]-2][self.coordinates[1]]==3):
length = len(canonsList)
for i in range(length):
Canon = canonsList[i]
if(Canon.coordinates[0]==self.coordinates[0]-2 and Canon.coordinates[1]==self.coordinates[1]-1 and Canon.health!=0):
Canon.health -= 1
if(Canon.coordinates[0]==self.coordinates[0]-2 and Canon.coordinates[1] == self.coordinates[1] and Canon.health!=0):
Canon.health -= 1
if(Canon.health == 0):
COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1] = 0
COC.idArray[self.coordinates[0]-2][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1]==4 or COC.idArray[self.coordinates[0]-2][self.coordinates[1]]==4):
Townhall.health -= 1
if(Townhall.health == 0):
COC.idArray[self.coordinates[0]-2][self.coordinates[1]-1] = 0
COC.idArray[self.coordinates[0]-2][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1]!=0 or COC.idArray[self.coordinates[0]+1][self.coordinates[1]]!=0):
print(1)
if(COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1]==7 or COC.idArray[self.coordinates[0]+1][self.coordinates[1]]==7):
length = len(wallsList)
for i in range(length):
Wall = wallsList[i]
if(Wall.coordinates[0]==self.coordinates[0]+1 and Wall.coordinates[1]==self.coordinates[1]-1 and Wall.health!=0):
print(1000)
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1] = 0
if(Wall.coordinates[0]==self.coordinates[0]+1 and Wall.coordinates[1] == self.coordinates[1] and Wall.health!=0):
print(1000)
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]+1][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1]==2 or COC.idArray[self.coordinates[0]+1][self.coordinates[1]]==2):
length = len(hutsList)
print(1)
for i in range(length):
Hut = hutsList[i]
if(Hut.coordinates[0]==self.coordinates[0]+1 and Hut.coordinates[1]==self.coordinates[1]-1 and Hut.health!=0):
Hut.health -= 1
if(Hut.coordinates[0]==self.coordinates[0]+1 and Hut.coordinates[1] == self.coordinates[1] and Hut.health!=0):
Hut.health -= 1
if(Hut.health == 0):
COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1] = 0
COC.idArray[self.coordinates[0]+1][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1]==3 or COC.idArray[self.coordinates[0]+1][self.coordinates[1]]==3):
length = len(canonsList)
for i in range(length):
Canon = canonsList[i]
if(Canon.coordinates[0]==self.coordinates[0]+1 and Canon.coordinates[1]==self.coordinates[1]-1 and Canon.health!=0):
Canon.health -= 1
if(Canon.coordinates[0]==self.coordinates[0]+1 and Canon.coordinates[1] == self.coordinates[1] and Canon.health!=0):
Canon.health -= 1
if(Canon.health == 0):
COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1] = 0
COC.idArray[self.coordinates[0]+1][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1]==4 or COC.idArray[self.coordinates[0]+1][self.coordinates[1]]==4):
Townhall.health -= 1
if(Townhall.health == 0):
COC.idArray[self.coordinates[0]+1][self.coordinates[1]-1] = 0
COC.idArray[self.coordinates[0]+1][self.coordinates[1]] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2]!=0 or COC.idArray[self.coordinates[0]][self.coordinates[1]-2]!=0):
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2]==7 or COC.idArray[self.coordinates[0]][self.coordinates[1]-2]==7):
length = len(wallsList)
for i in range(length):
Wall = wallsList[i]
if(Wall.coordinates[0]==self.coordinates[0]-1 and Wall.coordinates[1]==self.coordinates[1]-2 and Wall.health!=0):
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2] = 0
if(Wall.coordinates[0]==self.coordinates[0] and Wall.coordinates[1] == self.coordinates[1]-2 and Wall.health!=0):
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]][self.coordinates[1]-2] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2]==2 or COC.idArray[self.coordinates[0]][self.coordinates[1]-2]==2):
length = len(hutsList)
for i in range(length):
Hut = hutsList[i]
if(Hut.coordinates[0]==self.coordinates[0]-1 and Hut.coordinates[1]==self.coordinates[1]-2 and Hut.health!=0):
Hut.health -= 1
if(Hut.coordinates[0]==self.coordinates[0] and Hut.coordinates[1] == self.coordinates[1]-2 and Hut.health!=0):
Hut.health -= 1
if(Hut.health == 0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2] = 0
COC.idArray[self.coordinates[0]][self.coordinates[1]-2] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2]==3 or COC.idArray[self.coordinates[0]][self.coordinates[1]-2]==3):
length = len(canonsList)
for i in range(length):
Canon = canonsList[i]
if(Canon.coordinates[0]==self.coordinates[0]-1 and Canon.coordinates[1]==self.coordinates[1]-2 and Canon.health!=0):
Canon.health -= 1
if(Canon.coordinates[0]==self.coordinates[0] and Canon.coordinates[1] == self.coordinates[1]-2 and Canon.health!=0):
Canon.health -= 1
if(Canon.health == 0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2] = 0
COC.idArray[self.coordinates[0]][self.coordinates[1]-2] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2]==4 or COC.idArray[self.coordinates[0]][self.coordinates[1]-2]==4):
Townhall.health -= 1
if(Townhall.health == 0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]-2] = 0
COC.idArray[self.coordinates[0]][self.coordinates[1]-2] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1]!=0 or COC.idArray[self.coordinates[0]][self.coordinates[1]+1]!=0):
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1]==7 or COC.idArray[self.coordinates[0]][self.coordinates[1]+1]==7):
length = len(wallsList)
for i in range(length):
Wall = wallsList[i]
if(Wall.coordinates[0]==self.coordinates[0]-1 and Wall.coordinates[1]==self.coordinates[1]+1 and Wall.health!=0):
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1] = 0
if(Wall.coordinates[0]==self.coordinates[0] and Wall.coordinates[1] == self.coordinates[1]+1 and Wall.health!=0):
Wall.health -= 1
if(Wall.health==0):
COC.idArray[self.coordinates[0]][self.coordinates[1]+1] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1]==2 or COC.idArray[self.coordinates[0]][self.coordinates[1]+1]==2):
length = len(hutsList)
for i in range(length):
Hut = hutsList[i]
if(Hut.coordinates[0]==self.coordinates[0]-1 and Hut.coordinates[1]==self.coordinates[1]+1 and Hut.health!=0):
Hut.health -= 1
if(Hut.coordinates[0]==self.coordinates[0] and Hut.coordinates[1] == self.coordinates[1]+1 and Hut.health!=0):
Hut.health -= 1
if(Hut.health == 0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1] = 0
COC.idArray[self.coordinates[0]][self.coordinates[1]+1] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1]==3 or COC.idArray[self.coordinates[0]][self.coordinates[1]+1]==3):
length = len(canonsList)
for i in range(length):
Canon = canonsList[i]
if(Canon.coordinates[0]==self.coordinates[0]-1 and Canon.coordinates[1]==self.coordinates[1]+1 and Canon.health!=0):
Canon.health -= 1
if(Canon.coordinates[0]==self.coordinates[0] and Canon.coordinates[1] == self.coordinates[1]+1 and Canon.health!=0):
Canon.health -= 1
if(Canon.health == 0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1] = 0
COC.idArray[self.coordinates[0]][self.coordinates[1]+1] = 0
if(COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1]==4 or COC.idArray[self.coordinates[0]][self.coordinates[1]+1]==4):
Townhall.health -= 1
if(Townhall.health == 0):
COC.idArray[self.coordinates[0]-1][self.coordinates[1]+1] = 0
COC.idArray[self.coordinates[0]][self.coordinates[1]+1] = 0

Code smell: Many branches(cyclomatic complexity), long lines(god lines)

Suggested refractor

  • Find and refractor common code into functions
  • Format properly

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.