저자: Michał Powała
소스 저장소: two-heroes-fight-simulation
두 영웅의 전투 시뮬레이션
이 저장소에는 다양한 방식으로 접근한 특정 작업(이 파일 아래)에 대한 솔루션이 포함되어 있습니다. (완료된) 각 접근 방식에는 자체 분기와 태그가 있습니다. 응용 프로그램은 cli 형식으로 실행 가능합니다.
이 저장소의 목적은 (나에게) 깨끗한 코드와 약간의 좋은 코드 디자인을 연습하는 것입니다.
- OOP의 네 가지 기둥(SOLID에 초점을 맞추면 저절로 나타납니다)
- 견고한 원칙
- 단일 책임(각 수업마다 고유한 임무가 있음)
- 개방형/폐쇄형(다양한 접근 방식을 사용하기 시작했을 때 내부 대부분은 그대로 유지되었으며 새 기능을 추가하기만 하면 되었습니다)
- Liskov 대체 원칙(내 코드는 필요한 경우 추상화를 사용하고 기본 구현을 인식하지 못합니다. 예를 들어 Unit 및 Colleague 클래스를 살펴보세요)
- 인터페이스 분리 원칙(하나의 큰 인터페이스 대신 여러 개의 작은 인터페이스)
- 종속성 반전 원칙(클래스가 인스턴스화되는 유일한 장소는 run.php 스크립트와 팩토리이며 Randomizer를 살펴보세요. 조롱할 수 있습니다! 어떤 클래스에서도 직접 rand()를 사용하지 않습니다)
- 디자인 패턴
- 데코레이터(src/Modifier)
- 팩토리 메소드
- 관찰자 패턴(적절한 분기)
- 중재자 패턴(적절한 분기)
- DDD 전술 패턴
- 값 개체(src/속성)
- 집계(src/Unit - 여기에 캡슐화할 수 있는 모든 논리 비트가 여기에 있음)
- 도메인 서비스(TurnService)
- 애플리케이션 서비스(GamePlayService)
- 공장(공장)
- 이벤트(src/Event)(예, 대신 이벤트 버스를 사용할 수 있습니다)
- 느슨한 결합(SOLID에서 발생)
작업/이벤트 로거, 오류 로거, 프린터(리더) 및 핵심 로직은 모두 서로 느슨하게 결합되어 있습니다. - TDD
솔직히 말해서 실패한 테스트를 먼저 구현한 다음 테스트가 통과한 후 소스 코드를 구현하는 것은 순수한 TDD가 아니지만(실용적이지 않다고 생각합니다) 추상화 수준이나 클래스를 만든 후 즉시 테스트하고 다음과 같은 경우 사소한 버그를 모두 수정했습니다. 내가 생각하지 못한 필요한 오류 또는 논리적 오류. 그렇기 때문에 run.php 스크립트(애플리케이션의 진입점)를 구현하고 마지막 단계에서 이를 수행했을 때 코드가 작동했습니다! 나는 그것이 충분하고 순수한 TDD가 필요하지 않다고 생각합니다.
실행 방법
- docer 실행:
docker-compose up -d
- 애플리케이션 실행:
docker-compose exec cli php run.php
- 단위 테스트 실행
docker-compose exec cli vendor/bin/phpunit tests/
일
Orderus와 짐승 사이의 전투 시뮬레이션을 만듭니다. 전투가 시작될 때마다 다음 규칙에 따라 다른 통계를 지닌 야수와 오더루스가 생성됩니다.
- 순서:
- 체력: 70 - 100
- 힘: 70 - 80
- 방어: 45 – 55
- 속도: 40 – 50
- 행운: 10% - 30%(0%는 행운이 없음을 의미하고 100%는 항상 행운을 의미함)
- 추가 스킬:
- 신속한 공격: 공격할 차례인 동안 두 번 공격합니다. 공격할 때마다 이 스킬을 사용할 확률은 10%입니다.
- 마법 방패: 적이 공격할 때 평소 피해의 절반만 받습니다. 20% 변경이 있습니다. 그는 방어할 때마다 이 스킬을 사용하게 됩니다.
- 짐승:
- 건강: 60 - 90
- 힘: 60 - 90
- 방어: 40 – 60
- 속도: 40 – 60
- 행운: 25% - 40%
게임플레이 규칙:
- 첫 번째 공격은 속도가 빠른 플레이어가 수행합니다. 두 플레이어의 속도가 같으면 운이 가장 좋은 플레이어가 공격을 계속합니다.
- 공격 후 플레이어는 역할을 바꿉니다. 이제 공격자는 방어하고 방어자는 공격합니다.
- 공격자가 가한 피해는 다음 공식으로 계산됩니다.
Damage = Attacker strength – Defender defence
- 피해량은 방어자의 체력에서 차감됩니다. 방어자가 그 턴에 운이 좋다면 공격자는 명중을 놓치고 피해를 입지 않을 수 있습니다.
- Orderus의 기술은 확률에 따라 무작위로 발생하므로 매 턴마다 이를 고려하십시오.
- 플레이어 중 한 명이 체력이 없거나 턴 수가 20에 도달하면 게임이 종료됩니다.
- 애플리케이션은 매 턴마다 무슨 일이 일어났는지, 어떤 스킬이 사용되었는지(있는 경우), 피해, 방어자의 남은 체력 등의 결과를 출력해야 합니다.
- 최대 라운드 수에 도달하기 전에 승자가 있는 경우 승자를 선언해야 합니다.
가지와 태그
- 가지: 베이스; 태그: 기본 실행 앱:
아직 인쇄를 지원하지 않는 기본 솔루션(핵심 기능, 단위 테스트됨) 포함 - 분기: 관찰자 패턴; 태그: 실행 중인 앱 관찰자 패턴:
base
브랜치의 모든 코드를 포함하고 관찰자 패턴을 사용하여 인쇄 및 로깅으로 확장합니다. - 분기: 중재자 패턴; 태그: 실행 중인 앱 중재자 패턴:
base
분기의 모든 코드를 포함하고 중재자 패턴을 사용하여 인쇄 및 로깅으로 확장합니다.
더 많은 분기와 접근 방식이 추가될 예정입니다...
현재 분기: 기본
설명의 말씀
가장 쉽고 가장 '웹 앱' 솔루션은 외부 또는 자체 제작 이벤트 버스를 사용하는 것이지만 디자인 패턴을 가지고 놀고 싶습니다(언젠가 해당 솔루션을 추가할 수도 있음).
TODO
- 미스 능력을 구현하는 것을 잊었습니다 ...
- MagicShield 데코레이터에 존재하지 않는 위임 문제를 수정했습니다.