Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored mafia and mafia_param #18

Open
wants to merge 15 commits into
base: dev
Choose a base branch
from
Open

Conversation

aeirya
Copy link

@aeirya aeirya commented Sep 16, 2020

did some stuff to increase readability and code quality:

  • commented code.
  • reduced cognitive complexity of god_page function
  • refactored some of the code into functions
  • removed duplicate code
  • split mafia_param code into multiple files
  • game now uses json to store it's configuration and texts
  • added some whitespace
  • converted player class into a data class

Also added some functionality:

  • moved player related code from mafia into its own class
  • added team and role classes
    (todo:
    . use these to refer to roles instead of strings
    . add all roles)

.using player var instead of direct access to array
. moved request filtering to a function
. edited player class
    converted to a data class
    added functions die, is_alive, ban, unban,  switch_ban
. added max_comments function
added functions to allow backward compatibility.
ready to pull request.
	converted request mapper to a dict,
	handled invalid requests better
working on the role module.
(gets teams from the json)
and their teams are hardcored into code (and removed from json)
@sadrasabouri
Copy link
Owner

did some stuff to increase readability and code quality:

  • commented code.
  • reduced cognitive complexity of god_page function
  • refactored some of the code into functions
  • removed duplicate code
  • split mafia_param code into multiple files
  • game now uses json to store it's configuration and texts
  • added some whitespace
  • converted player class into a data class

Also added some functionality:

  • moved player related code from mafia into its own class
  • added team and role classes
    (todo:
    . use these to refer to roles instead of strings
    . add all roles)

If you are not going to solve todo section in this PR, please issue it.

@aeirya
Copy link
Author

aeirya commented Sep 17, 2020

did some stuff to increase readability and code quality:

  • commented code.
  • reduced cognitive complexity of god_page function
  • refactored some of the code into functions
  • removed duplicate code
  • split mafia_param code into multiple files
  • game now uses json to store it's configuration and texts
  • added some whitespace
  • converted player class into a data class

Also added some functionality:

  • moved player related code from mafia into its own class
  • added team and role classes
    (todo:
    . use these to refer to roles instead of strings
    . add all roles)
  • added enums for roles, replacing their string representation in the code.
  • added a few classes, trying to give the project a better design.
  • silenced code factor warnings.

needless to say this issue links directly to #6

Copy link
Owner

@sadrasabouri sadrasabouri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @aeirya
Thanks for your PR, I reviewed it and there was some points you should consider.
After resolving them I'll check performance (respected to the time of server actions).
Remember to keep it as simple as possible so that anyone can easily read the code and contribute to it.

def get_repitition(self) -> int:
return int(mafia_params.nRoles[self.name])

# get desription(self) -> str here
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these comments and issue them.

)

class Roles(enum.Enum):
#could've used enum.auto()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this too, you can talk about your strategies and decisions in PR comments so that one who want to read about it can find his/her answer easily and keep code simple too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok .. it was actually a note for myself which I forgot to remove from code

return Roles["_".join([word.upper() for word in string.split()])]

roles = dict([(r, r.to_role()) for r in Roles])
ordered_roles = [roles.get(get(key)) for key in mafia_params.ordered_roles]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last new line is common for code files.
Please consider it in your files.

@@ -1,110 +1,171 @@
from sys import argv
from random import randrange, shuffle
from typing import Callable, Dict, List, Text, Tuple
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe typing can help us.
Most of these variables are in-app variables and have controlled values so we don't need typing.
Instead of that you can make proper docstring for your functions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally don't see any reason not to use it.
Sure we could use docstrings too but for more rewarding info imo.
Using too much doc is just gonna get our code cluttered and slow to read by others.
But still, I could remove them after after I'm done with those functions, if u insist.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of variable assignment is reminding Rust for me and I don't want the code be that much frightening to look at it, for instance it may be obvious for reader to understand that is_... may return True or False.

self.n_players = n_players
self.roles = roles

def is_ip_valid(self, ip : str) -> bool:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_repeated

Comment on lines +109 to +112
def kill(player : Player) -> None:
# notice banned players cannot be killed
if player.is_alive():
player.die()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add another if which makes player alive if kill is pressed again after player's death.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.
also checks for is_banned now

Comment on lines +134 to +147
def get_requests() -> List[Tuple[str, Player]]:
requests = []
for key in request_mapper.keys():
ip = request.args.get(key)

if ip is None:
continue
if not player_manager.is_ip_valid(ip):
print("invalid ip / request: ", ip, f"({key})")
return -1

player = player_manager.get_player(ip)
requests.append((key, player))
return requests
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get the point of this part please explain it for me and it's use in application

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's supposed to check for every possible request type in our request object, and check if the ip address is valid (it was previously done by duplicated lines of ip checking).

what you may find strange at first is that this function returns a list of request types and their arguments.
it isn't uncommon to split a big function to smaller ones with different responsibilities, which I did for the god function.
tho the main reason i made get_requests was that fact i was unsure if it is possible for a request object to have multiple args or not (and i actually guess the answer is no, which means i'll probably clean this part a little bit soon)

Comment on lines -2 to +18
"""A player in mafia game"""
def __init__(self, ip, username, role, image_name):
self.ip = ip
self.username = username
self.state = "alive"
self.role = role
self.image_name = image_name
self.comment = False
ip : str
username : str
role : str
image_name : str
state : PlayerState = PlayerState.ALIVE
comment : bool = False
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change it back.
No need for typing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data classes require you to do typing. (it just doesn't work if we don't)
needless to say, it is a much more intuitive way of making classes which are data holder.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you say it, that's OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants