π― μμΉ¨μ μ½λ©μ μλ£νκ³ , leetcodeμ Gitμ μ°λνμ¬ νμ΄λ₯Ό μλ£νμ¬ μλ μ
λ‘λ λ μ μλλ‘ νμλ€.
κ·Έλ¦¬κ³ , κ°μΈ κ³Όμ μ λμ μμλ₯Ό μ μΈν νμ μμλ₯Ό ꡬννλλ° μλ£νμλ€.
bool isAnagram(String s, String t) { // λ λ¬Έμμ΄μ κΈΈμ΄κ° λ€λ₯΄λ©΄ μ λκ·Έλ¨μ΄ μλ if (s.length != t.length) return false; // κ° λ¬Έμμ΄μ λ¬Έμλ₯Ό μ λ ¬ν ν λΉκ΅ List<String> sortedS = s.split('')..sort(); List<String> sortedT = t.split('')..sort(); return sortedS.join() == sortedT.join(); }
β leetcode μ°λ
π leethubλ₯Ό μ΄μ©ν΄μ Gitμ μ°λνκ³ , μλμΌλ‘ 컀λ°ν΄μ£Όλ νμ₯ νλ‘κ·Έλ¨μ΄ μμ΄μ μ leetcode λΌλ μ μ₯μλ₯Ό λ§λ€μλ€.
κ·Έλ¦¬κ³ κ³μ μ°λκΉμ§λ μλ£νλλ°, λ¬Έμ νμ΄ ν λλ₯΄λ©΄ μ°λμ΄ μλμ΄μ λ¬Έμ κ° λμΌμ§ μ°Ύλ€κ° μ¨κ²¨μ Έμλ.. μλ‘μ΄ λ²μ μΌλ‘ κ΅μ²΄ν΄μ ν΄κ²°νλ€.
π
main.dartimport 'package:rpg_game/game.dart'; // void main(List<String> arguments) { var game = Game(); game.startGame(); }π¬ ν΄λΉ κ²μ ν¨μλ§ νΈμΆνμ¬ mainμ κΈ°λ₯μ μλ£νμλ€.
π
character.dartvoid attackMonster(Monster monster) { print("$nameμ΄(κ°) ${monster.name}μκ² $attackμ λ°λ―Έμ§λ₯Ό μ νμ΅λλ€.\n"); monster.hp -= attack; } // λ°©μ΄ void defend(Monster monster) { if (monster.attack >= defense) { var addHp = monster.attack - defense; hp += addHp; print("$nameμ΄(κ°) λ°©μ΄νμΈλ₯Ό μ·¨νμ¬ $addHp λ§νΌ 체λ ₯μ μ»μμ΅λλ€."); } }π¬ μΊλ¦ν°μ 곡격 λ‘μ§μ ꡬννμ¬ λͺ¬μ€ν°μ νΌκ° κ·Έλ§νΌ λ§μ΄λμ€ λλλ‘ νμλ€.
π¬ λ°©μ΄ λ‘μ§λ ꡬνμ μλ£νλλ°, νΌκ° μ°¨λ λ‘μ§μ΄λΌ λͺ¬μ€ν°μ 곡격λ ₯μ΄ νμνκΈ° λλ¬Έμvoid defend(Monster monster)μ΄λ°μμΌλ‘ λͺ¬μ€ν° μ 보λ₯Ό λ°μμλ€.
π
monster.dartvoid attackCharacter(Character character) { print("$nameμ ν΄"); print("$nameμ΄(κ°) ${character.name}μκ² $attackμ λ°λ―Έμ§λ₯Ό μ νμ΅λλ€."); character.hp -= (attack - character.defense); }π¬ μμ λμΌνκ² κ³΅κ²© λ‘μ§μ ꡬννμκ³ , μΊλ¦ν°μ μ 보λ₯Ό λ°μμλ€.
π
game.dart// μ κ·μ: νκΈ(κ°-ν£), μλ¬Έ λμλ¬Έμ(A-Za-z)λ§ νμ© final regex = RegExp(r'^[κ°-ν£a-zA-Z]+$'); // 쑰건 κ²μ¬ if (charName.trim().isEmpty) { print("μ΄λ¦μ λΉμ΄ μμ μ μμ΅λλ€."); exit(1); } if (!regex.hasMatch(charName)) { print("μ΄λ¦μλ μ«μλ νΉμλ¬Έμλ₯Ό μ¬μ©ν μ μμ΅λλ€."); exit(1); }π¬ νκΈ, μλμλ¬Έμλ§ νμ©νκΈ° μν΄ μ κ·μμ μ¬μ©ν΄μ μ«μλ νΉμλ¬Έμλ₯Ό κ±Έλ¬μ£Όκ³ , κ³΅λ°±μ΄ μ‘΄μ¬ν κ²½μ°λ κ±Έλ¬μ£Όμλ€.
character = Load.loadChar(charName); monster = Load.loadMonster(character.defense); character.showStatus(); . . var isWin = await battle(randomMonster); if (!isWin) { print("${character.name}μ΄(κ°) μ°λ¬μ‘μ΅λλ€."); break; } print("${randomMonster.name}λ₯Ό μ²μΉνμμ΅λλ€."); if (monster.isEmpty) { print("μΆνν©λλ€! λͺ¨λ λͺ¬μ€ν°λ₯Ό 물리쳀μ΅λλ€."); break; } print("λ€μ λͺ¬μ€ν°μ λκ²°νμκ² μ΅λκΉ? y/n"); bool isContinue = false; while (true) { String? next = stdin.readLineSync()!.trim(); if (next == "Y" || next == "y") { isContinue = true; break; } else if (next == "N" || next == "n") { isContinue = false; break; } print("λ€μ μ λ ₯ν΄μ£ΌμΈμ."); } if (!isContinue) break; }π¬ μΊλ¦ν°μ λͺ¬μ€ν°μ λ°μ΄ν°λ₯Ό λ‘λν΄μ€κ³ , λ°°νμ μ§ννλ€. κ·Έλ¦¬κ³ λ°°νμ΄ μλ£κ° λμμ λ, μ΄κ²Όλμ§, μ‘λμ§ λ°ννμ¬ νλ μ΄μ΄κ° μ‘μ κ²½μ° κ²μ μ€λ²λ‘ μ μ₯ν μ§ μ ννκ² νλ€.
κ·Έκ² μλλΌλ©΄ λͺ¬μ€ν°λ₯Ό μ°λ €νΈλ ΈμΌλ λ€μ λͺ¬μ€ν°μ μΈμΈμ§ μ νμ§λ₯Ό μ 곡νλλ° μ΄λ λ€λ₯Έ κ°μ μ λ ₯νλ©΄ λ€μ μ λ ₯νκ²λ μ²λ¦¬ν΄μ€λ€.
λ°°νμ λ°λ³΅νκ³monster.isEmptyλ₯Ό μ¬μ©νμ¬ λμ΄μ λ¨μμλ λͺ¬μ€ν°κ° μμΌλ©΄ μ ν¬λ₯Ό μ’ λ£νλλ‘ νλ€.
// κ²μ κ²°κ³Ό μ μ₯ print("κ²°κ³Όλ₯Ό μ μ₯νμκ² μ΅λκΉ? (y/n)"); String? saveInput = stdin.readLineSync()!.trim(); if (saveInput == "Y" || saveInput == "y") { var result = "${character.name},${character.hp},${character.hp > 0 ? "μΉλ¦¬" : "ν¨λ°°"}"; Save.saveData(result); }π¬ κ²μ κ²°κ³Όλ₯Ό μ μ₯νλ λ‘μ§λ ꡬννμ¬ ν΄λΉ μ ν¬ κ²°κ³Ό λ°μ΄ν° κ°μ μ λ¬ν΄ νΈμΆνλ€.
Future<bool> battle(Monster monster) async { . . if (action == "1") { character.attackMonster(monster); await Future.delayed(Duration(seconds: 2)); monster.attackCharacter(character); monster.showStatus(); } else if (action == "2") { character.defend(monster); } else { print("μλͺ»λ μ λ ₯μ λλ€. λ€μ μ λ ₯ν΄μ£ΌμΈμ!"); continue; } // μ ν¬ μ’ λ£ νμΈ if (character.hp <= 0) { return false; } else if (monster.hp <= 0) { Monster monsterList = monster; // monsterList.removeAt(index); return true; }π¬ κ·Έλ¦¬κ³ λ°°ν λ‘μ§μμ νλμ μ λ ₯λ°κ³ 곡격 λ° λ°©μ΄λ₯Ό νκ²λ ꡬννλ€.
λ€λ₯Έ κ°μ μ λ ₯ν κ²½μ° λ€μ μ λ ₯νλλ‘ μ²λ¦¬νμκ³ , μ ν¬ μ’ λ£ μ‘°κ±΄μ μ€μ ν΄ μμλ 보μ΄μ§ μμ§λ§ λ°λ³΅λ¬Έμ λΉ μ Έλμ€λλ‘ νλ€.
π
data.dart// λ°μ΄ν° νμ κ²μ¦ if (parts.length != 3) { print("λͺ¬μ€ν° λ°μ΄ν°κ° μλͺ»λμμ΅λλ€."); exit(1); } var maxAttack = int.parse(parts[2]); var mon = Monster( name: parts[0], hp: int.parse(parts[1]), attack: 1 + defense + Random().nextInt(maxAttack - defense + 1), defense: 0, ); // 곡격λ ₯ κ²μ¦ if (mon.attack <= defense) { print("λͺ¬μ€ν°μ 곡격λ ₯μ μΊλ¦ν°μ λ°©μ΄λ ₯λ³΄λ€ λμμΌν©λλ€."); exit(1); } monster.add(mon); } return monster; } }π¬ λ°μ΄ν° νμμ
parts.lengthλ‘ νμΈνκ³ , 곡격λ ₯ κ²μ¦λ μ§νν΄μ€λ€.
μ¬κΈ°μdefenseκ° κ°λ₯ν μ΄μ λ λͺ¬μ€ν° λ°μ΄ν° λ‘λ μ μΊλ¦ν°μ λ°©μ΄λ ₯ κ°μ λ°μμ€λλ‘ μ€μ νκΈ° λλ¬Έμ΄λ€.
static Character loadChar(String name) { final file = File("assets/character.txt"); // νμΌ μ¬λΆ νμΈ if (!file.existsSync()) { print("μΊλ¦ν° νμΌμ΄ μ‘΄μ¬νμ§ μμ΅λλ€."); exit(1); } String line = file.readAsLinesSync(encoding: utf8).first; List<String> parts = line.split(","); // λ°μ΄ν° νμ κ²μ¦ if (parts.length != 3) { print("μΊλ¦ν° λ°μ΄ν°κ° μλͺ»λμμ΅λλ€."); exit(1); } int hp = int.parse(parts[0]); int attack = int.parse(parts[1]); int defense = int.parse(parts[2]); return Character(name: name, hp: hp, attack: attack, defense: defense); } }π¬ μΊλ¦ν° λ°μ΄ν°λ λΆλ¬μ€λλ°, μ¬κΈ°μ
string nameμΌλ‘ μ λ ₯λ°μ name κ°μ λ°μμ€λλ‘ νμ¬ λ£μ΄μ€λ€.
λμΌνκ² νμΌ μ¬λΆμ νμμ κ²μ¦νλ€.
// λ°μ΄ν° μ μ₯ class Save { static saveData(String result) { var saveresult = result; // νμΌ μμ± final file = File('assets/result.txt'); file.writeAsStringSync(saveresult); print("μ μ₯μ΄ μλ£λμμ΅λλ€!"); } }π¬ νμΌμ μ μ₯νλ λ©μλλ₯Ό νΈμΆνκΈ° μ½κ² μ μμΌλ‘ λ°κΏμ£Όκ³ , μ§μ νμΌμ κ²°κ³Ό μ μ₯λλλ‘ κ΅¬ννλ€.
β νΈμΆ μ€λ₯
var utils = Utils(); var result = utils.add();π¬ νΈμΆμ΄ μλμ΄μ μ°Ύμ보λ importλ§ λμ΄μμ΄μ ν΄λμ€ λͺ μ μ°κ³ μΆλ€λ©΄ λ¨Όμ λ³μλ₯Ό λ§λ ν μ¬μ©ν΄μΌ νλ κ±Έ λ€μ νμΈνκ² λμλ€. μ½λ νλ¦λλ‘ μ°λ€λ³΄λ μ΄κ±Έ κΉλΉ‘νλ κ²
π¬ μλ₯Ό λ€μ΄var result = Utils().add()μ΄λ°μμΌλ‘ μ¬μ©νλ λ°©λ²μ΄ μλλ°, λ³λ‘ μ’μ§λͺ»ν λ°©λ²μ΄λΌκ³ νλ€. μμ μ½λλ₯Ό μλ΅νμ¬ μ¬μ©ν κ²μ΄λΌκ³ νλλ°...
μλ¬΄νΌ μ λ³μ μ μΈμ νκ³ ν΄λμ€ λ£λκ±Έ κΉλ¨Ήμ΄μ λ‘λν λ ν΄κ²°μ΄ μλμλλ°staticμ μ¬μ©νμ¬ ν΄κ²°μ μλ£νλ€.
β νμΌ λ‘λ
final file = File("../assets/monster.csv"); // κΈ°μ‘΄ μ½λ final file = File("assets/monster.txt"); // λ³κ²½λ μ½λπ¬ μ΄κ² μ€νμ΄
bin/main.dartλΌμ ..μΌλ‘ ν΄λλ₯Ό λμ€κ³ ν΄λΉ νμΌμ μ€νν΄μ£Όλ € νλλ°, μ μ΄μ dart run bin/main.dart μ΄λ°μμΌλ‘ λ리기 λλ¬Έμ μκ΄μ΄ μλ€κ³ νλ€.
κ·Έλμ../μ μ κ±°νκ³ , csv κ°μ κ²½μ° json μ²λΌ κ·Έ νμΌ μ κ΅¬μ± ννλ₯Ό λ»νλ λ§μ΄μλ κ²μ΄λΌ,.txtνμμΌλ‘ νμΌμ΄ μκΈ° λλ¬Έμ λ°κΎΈμ΄μ£Όμλ€.
β λ°μ΄ν° κ°
var maxAttack = int.parse(parts[2]); var mon = Monster( name: parts[0], hp: int.parse(parts[1]), attack: 1 + defense + Random().nextInt(maxAttack - defense + 1), defense: 0, ));π¬
monsterμ μ΅λ 곡격λ ₯κ³Ό μΊλ¦ν°μ λ°©μ΄λ ₯μ μ¬μ΄ κ°μ λλ€μΌλ‘ μ μ νμ¬ κ³΅κ²©λ ₯μΌλ‘ μ μ ν΄μΌνλλ°, μ΄minmaxμ΄κ²μ dart 곡μ ννμ΄μ§μμ μ¬μ©νλ λ²μ μ°Ύμλ€.
βattack: defense + Random().nextInt(maxAttack - defense + 1)μ΄κ² κ·Έ μ μ μ½λμΈλ° μ€λ₯κ° λ°μνλ€.
κ³μ λ°μ λλ €λ³΄λ λ°μν λλ μκ³ μμ λλ μμλ€.
μ΄μ νμΈμ μν΄μ${mon.attack}${char.defense}μ΄λ κ² ν΄λΉ κ°μ νμΈνκ³ μ€λ₯ λ°μν λκΉμ§ λλ €λ³΄λ 5, 5 μ΄λ°μμΌλ‘ κ°μ κ°μ΄ λμλ κ²μ΄λ€.
μ΅λκ°μλ +1μ νμ¬ μ΅λκ°μ μ μ€μ νλλ° μ΅μκ°μλ +1μ ν΄μ£Όμ§ μμμ κ°μ κ°μ΄ λμμ λ°λ―Έμ§κ° 0μ΄ λλ μν©μ΄ λ°μν κ²μ΄λ€.
βοΈ λ€νμ€λ½κ²λ μ΄κ±Έ μμΈ μ²λ¦¬λ₯Ό ν΄λμ΄μ ν΄λΉ λΆλΆμ νμΈνκ³ , μμ μ²λΌ+1μ μΆκ°νμ¬ ν΄κ²°νμλ€.
β μΆλ ₯ λ©μΈμ§κ° μ°λ¬μμ λΉ λ₯΄κ² λΆμ΄μ μΆλ ₯λκΈ° λλ¬Έμ κ°λ μ±μ΄ λ¨μ΄μ§κ³ , νλ²μ λ§μ μ λ³΄λ‘ μ΄λ€ μ λ³΄κ° μΆλ ₯λμλμ§ νμ μ΄ νλ€μλ€.
π¬print("$nameμ΄(κ°) ${monster.name}μκ² $attackμ λ°λ―Έμ§λ₯Ό μ νμ΅λλ€.\n");κ·Έλμ μ΄λ°μμΌλ‘ ν ν΄λ§λ€ λ¬Έμ₯μ΄ λμ€λλ‘ λμ΄μ£Όμλ€.
π¬ 그리κ³
Future,async,awaitλ₯Ό νμ©νμ¬await Future.delayed(Duration(seconds: 2));μΆλ ₯μ 2μ΄μ κ°κ²©μ μ£Όμλ€.
π μ΄λ₯Ό μν΄Future<bool> battleμ΄λ°μμΌλ‘ λ³κ²½ν΄μ£Όκ³ , λ€λ₯Έ κ³³μμ ν΄λΉbattle();μ νΈμΆν λ λ€μ μ½λλ‘ λμ΄κ°μ§ μλλ‘void startGame() async,var isWin = await battle(randomMonster);μ΄λ° μμΌλ‘ μμ μλ£ν΄μ£Όμλ€.
β μ΄ λΉλκΈ°μ λκΈ°λ νΈλ¬λΈ μν μ μΈκΉ κ³ λ―Όνλλ°, μκ°λ³΄λ€ κΈλ°©.. ν΄κ²°μ΄λκΉ λ¬Έμ μ νμ μ΄ μλμ΄μ μ¬κΈ°μ μμ±νλ€.
π¬ λ¬Έμ λ₯Ό μ°Ύμλλ° κ°μΈ νλ‘μ νΈ μ€ μ΄μ λ§₯μμ 컀λ°ν κ²μ μμ³μ€λ€λ κ²μ΄λ€. κ·Όλ° λλ¬λ³΄λ©΄ 컀λ°λμ΄μλ λ΄μ©λ€μ λ³Ό μκ° μλ κ²μ΄κ³ , λ¨μν λ΄ κΉ νμ΄μ§μμ 컀λ°μ λͺλ² νλμ§ μΈμ΄μ£Όμ§ μλλ€λ κ² π¦
β ν΄κ²° λ°©λ²
git config --global user.name git config --global user.emailπ¬ ν°λ―Έλμ μ΄λ°μμΌλ‘ μλμ°μ λ§₯ λλ€ μ΄λ€ μ΄λ¦κ³Ό μ΄λ©μΌμ΄ μ°λλμ΄ μλμ§ νμΈνλ€.
κ·Έλ¬λλ μ΄λ©μΌμ΄ κ΅¬κΈ λ©μΌκ³Ό κΉ λ©μΌ μ΄λ κ² λ¬λλ λ¬Έμ λ₯Ό λ°κ²¬νλ€.
git config --global user.name "λλ€μ" git config --global user.email "λ©μΌμ£Όμ"π¬ μ΄λ κ² λ€μ λ³κ²½ν λλ€μμ΄λ λ©μΌ μ£Όμλ₯Ό μ λ ₯νμ¬ λ³κ²½ν΄μ£Όμλ€.
κ·Έλμ μ΄λ©μΌμ λκ°μ΄ λ§λ€μ΄μ€¬κ³ ,git config --global user.emailλ₯Ό μ λ ₯νλ©΄ λ°λ κ²μ μ μ μλ€.
β κΈ°λ₯ ꡬν μλ£
βοΈ μΊλ¦ν° 곡격 λ° λ°©μ΄ λ‘μ§ μλ£
βοΈ λͺ¬μ€ν° 곡격 λ‘μ§ μλ£
βοΈ λ°°ν κΈ°λ₯ ꡬν μλ£
βοΈ μμΈ μ²λ¦¬ μλ£
βοΈ μΊλ¦ν° λ°μ΄ν° λ‘λ κΈ°λ₯ ꡬν μλ£
βοΈ λ°μ΄ν° μ μ₯ κΈ°λ₯ ꡬν μλ£
βοΈ νμΌ μμ λ° μμ
βοΈ μ½λ 리νν λ§ λ° λ²κ·Έ μμ μλ£
π± μμ λ©°μΉ λμλ μμ μ λ§μ΄ νλλ°, μ€λ λν μΌνκ² λ‘μ§λ€μ ꡬμ±νκ³ μμ νλ€ λ³΄λ λ λ§μ΄ ν κ² μ²λΌ 보μΈλ€.
λκ° μ€λ ν κ²λ λ§κ³ , μμ μ΄λ μμΈ μ²λ¦¬ν κ²λ λ§μλ κ² κ°μλ° λ¦μ μκ°μ΄μ§λ§ μλ£λ₯Ό νκΈ΄ νλ€.
λ§μ μμ νλ€λ³΄λ λ‘μ§ μ§λ κ²λ λ§κ³ , μ€λ₯ μμ λ μ’ λΉ¨λ¦¬λ λ μλ μμ΄μ λ΄κ° μ΄λ κ² λ§μ΄ ν΄λλ μΆμλ€.
κ·Όλ°, μ΄κ² μ’μ μμ λ°©λ²μ μλλΌκ³ νλκ² νλ¦λλ‘λ μλκ³ μμΈμ²λ¦¬λ κ±°μ λ€ ν΄λμλλ°, ν μ€νΈλ λ§μ§λ§μ λΆλ΄λΆλ΄ μ’ ν κ²½ν₯λ μμ΄μ λ΄μ λ§νλ€κ³ λ€λ₯Έκ±° λ¨Όμ νκΈ°λ³΄λ€ ν΄κ²°μ λ¨Όμ ν΄λ³ΌκΉλ μΆλ€.
μ΄κ² λ§νλκΉ μ¬μ΄κ±° λΆν° νμκ° λμκ³ , μ΄μ© λλ μ΄κ² λ§λ λ°©λ²μ΄κ² μ§λ§ μ§κΈμ μ’ λ λ΄κ° μ΄λ€ κ±Έ ꡬννκ³ , μλνλμ§ νμΈνλκ² λ μ€μνλκΉ.
π λ΄μΌμ μμΉ¨μ μ½λ©μ λ£κ³ μ¬μ κ° λλ€λ©΄ λμ κ³Όμ λ₯Ό μ‘°κΈ κ΅¬νν λ€μ κ³Όμ λ₯Ό μ μΆν μμ μ΄λ€.
κ·Έλ¦¬κ³ μ€νμ κ³Όμ νμ΄λ₯Ό λ£κ³ λ λ€μ λμ κ³Όμ λ¨μ λΆλΆλ€μ΄ μλ€λ©΄, μμκ±° κ°μ§λ§ κ·ΈλΆλΆ ꡬννκ³ μ νλ€.
μκ°μ΄ λ¨λλ€λ©΄ μΆκ° νμ΅μ μ§ννκ±°λ κ°μ΄ νμ΄ λ€μλκ±Έ TILμ μ 리νλ μκ°μ κ°μ§μ§ μμκΉ μΆλ€.