Merge pull request #15 from Degulleo/DO-33-오목-룰-적용하기

Do 33 오목 룰 적용하기
This commit is contained in:
Lim0_C 2025-03-18 11:19:14 +09:00 committed by GitHub
commit 2bea8956ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 20319 additions and 68 deletions

8
Assets/LYC.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2c121ebd683637b4a9f10f3360db1bd5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

19665
Assets/LYC/GameCopyLYC.unity Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c7eedd59cc78a7648a2168fd25540b88
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/LYC/Prefabs.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cdc13900aeb5f15469ac909354058ba5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,269 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &4527645627922892802
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6675599954136940932}
- component: {fileID: 999587919958738827}
- component: {fileID: 3838441490010372991}
- component: {fileID: 5432505654977179684}
m_Layer: 5
m_Name: Retry Button
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6675599954136940932
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4527645627922892802}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 662537649981192553}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -50, y: -100}
m_SizeDelta: {x: 228, y: 125.899994}
m_Pivot: {x: 1, y: 1}
--- !u!222 &999587919958738827
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4527645627922892802}
m_CullTransparentMesh: 1
--- !u!114 &3838441490010372991
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4527645627922892802}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 2b713a3fc08a07045823477e97022e09, type: 3}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &5432505654977179684
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4527645627922892802}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 3838441490010372991}
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 0}
m_TargetAssemblyTypeName: GameManager, Assembly-CSharp
m_MethodName: RetryGame
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
--- !u!1 &6877030451239157200
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 662537649981192553}
- component: {fileID: 2462059473707687523}
- component: {fileID: 9042688505538446270}
m_Layer: 5
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &662537649981192553
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6877030451239157200}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 6675599954136940932}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2462059473707687523
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6877030451239157200}
m_CullTransparentMesh: 1
--- !u!114 &9042688505538446270
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 6877030451239157200}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: Retry
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4281479730
m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 40
m_fontSizeBase: 40
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 1
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 67fa853934a50654381442493bf1bb7b
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -11988,7 +11988,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a98355720bed2234fb32d55fc1b0cce6, type: 3}
m_Name:
m_EditorClassIdentifier:
widthUnit: 15.5
widthUnit: 15
--- !u!114 &1612127712 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 2897735151576090782, guid: 42b665a12a9843240ac0860bf0eee63e, type: 3}
@ -18380,10 +18380,10 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_UiScaleMode: 1
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ReferenceResolution: {x: 1080, y: 1920}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3

View File

@ -13,10 +13,4 @@ public class CameraController : MonoBehaviour
_camera = GetComponent<Camera>();
_camera.orthographicSize = widthUnit / _camera.aspect / 2;
}
void Update()
{
}
}

View File

@ -9,4 +9,5 @@ public class Enums
public enum StoneState{ None, Selected, Blocked, LastPositioned }
public enum GameType{ None, SinglePlay, MultiPlay, Replay }
}

View File

@ -1,103 +1,357 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class BasePlayerState
{
public abstract void OnEnter(GameLogic gameLogic);
public abstract void OnExit(GameLogic gameLogic);
public abstract void HandleMove(GameLogic gameLogic, int row, int col);
public abstract void HandleNextTurn(GameLogic gameLogic);
public void ProcessMove(GameLogic gameLogic, Enums.PlayerType playerType, int row, int col)
{
gameLogic.fioTimer.PauseTimer();
gameLogic.SetNewBoardValue(playerType, row, col);
if (gameLogic.CheckGameWin(playerType, row, col))
{
GameManager.Instance.OpenConfirmPanel($"Game Over: {playerType} Win",() =>{});
gameLogic.EndGame();
}
else
{
//TODO: 무승부 확인
HandleNextTurn(gameLogic);
}
}
}
public class PlayerState : BasePlayerState
{
private Enums.PlayerType _playerType;
private bool _isFirstPlayer;
public PlayerState(bool isFirstPlayer)
{
_isFirstPlayer = isFirstPlayer;
_playerType = isFirstPlayer ? Enums.PlayerType.PlayerA : Enums.PlayerType.PlayerB;
}
public override void OnEnter(GameLogic gameLogic)
{
gameLogic.fioTimer.StartTimer();
//TODO: 첫번째 플레이어면 렌주 룰 확인
gameLogic.currentTurn = _playerType;
gameLogic.stoneController.OnStoneClickedDelegate = (row, col) =>
{
HandleMove(gameLogic, row, col);
};
}
public override void OnExit(GameLogic gameLogic)
{
//TODO: 렌주 룰 금수자리 초기화
gameLogic.fioTimer.InitTimer();
gameLogic.stoneController.OnStoneClickedDelegate = null;
}
public override void HandleMove(GameLogic gameLogic, int row, int col)
{
gameLogic.SetStoneSelectedState(row, col);
}
public override void HandleNextTurn(GameLogic gameLogic)
{
if (_isFirstPlayer)
{
gameLogic.SetState(gameLogic.secondPlayerState);
}
else
{
gameLogic.SetState(gameLogic.firstPlayerState);
}
}
}
public class AIState: BasePlayerState
{
public override void OnEnter(GameLogic gameLogic)
{
gameLogic.fioTimer.StartTimer();
//TODO: AI이식
}
public override void OnExit(GameLogic gameLogic)
{
gameLogic.fioTimer.InitTimer();
}
public override void HandleMove(GameLogic gameLogic, int row, int col)
{
ProcessMove(gameLogic, Enums.PlayerType.PlayerB,row, col);
}
public override void HandleNextTurn(GameLogic gameLogic)
{
gameLogic.SetState(gameLogic.firstPlayerState);
}
}
public class MultiPlayerState: BasePlayerState
{
public override void OnEnter(GameLogic gameLogic)
{
gameLogic.fioTimer.StartTimer();
}
public override void OnExit(GameLogic gameLogic)
{
gameLogic.fioTimer.InitTimer();
}
public override void HandleMove(GameLogic gameLogic, int row, int col)
{
}
public override void HandleNextTurn(GameLogic gameLogic)
{
}
}
public class GameLogic : MonoBehaviour
{
private Enums.PlayerType[,] _board;
private StoneController _stoneController;
public StoneController stoneController;
public Enums.PlayerType currentTurn;
public Enums.GameType gameType;
public BasePlayerState firstPlayerState;
public BasePlayerState secondPlayerState;
private BasePlayerState _currentPlayerState;
public FioTimer fioTimer;
private const int WIN_COUNT = 5;
//선택된 좌표
public int selectedRow;
public int selectedCol;
//마지막 배치된 좌표
public int lastRow;
public int lastCol;
private int _lastRow;
private int _lastCol;
public GameLogic(StoneController stoneController, Enums.GameType gameType)
private static int[][] _directions = new int[][]
{
new int[] {1, 0}, // 수직
new int[] {0, 1}, // 수평
new int[] {1, 1}, // 대각선 ↘ ↖
new int[] {1, -1} // 대각선 ↙ ↗
};
public GameLogic(StoneController stoneController, Enums.GameType gameType, FioTimer fioTimer = null)
{
//보드 초기화
_board = new Enums.PlayerType[15, 15];
_stoneController = stoneController;
this.stoneController = stoneController;
this.gameType = gameType;
selectedRow = -1;
selectedCol = -1;
lastRow = -1;
lastCol = -1;
currentTurn = Enums.PlayerType.PlayerA;
SetState(currentTurn);
_lastRow = -1;
_lastCol = -1;
//timer 초기화
if (fioTimer != null)
{
this.fioTimer = fioTimer;
this.fioTimer.InitTimer();
//timer 시간초과시 진행 함수
this.fioTimer.OnTimeout = () =>
{
if (currentTurn == Enums.PlayerType.PlayerA)
{
GameManager.Instance.OpenConfirmPanel($"Game Over: {Enums.PlayerType.PlayerB} Win",
() =>{});
EndGame();
}
else if (currentTurn == Enums.PlayerType.PlayerB)
{
GameManager.Instance.OpenConfirmPanel($"Game Over: {Enums.PlayerType.PlayerA} Win",
() =>{});
EndGame();
}
};
}
//TODO: 기보 매니저에게 플레이어 닉네임 넘겨주기
ReplayManager.Instance.InitReplayData("PlayerA","nicknameB");
switch (gameType)
{
case Enums.GameType.SinglePlay:
firstPlayerState = new PlayerState(true);
secondPlayerState = new PlayerState(false);
SetState(firstPlayerState);
break;
case Enums.GameType.MultiPlay:
//TODO: 멀티 구현 필요
break;
case Enums.GameType.Replay:
//TODO: 리플레이 구현
break;
}
}
//착수 버튼 클릭시 호출되는 함수
public void OnConfirm()
{
_currentPlayerState.ProcessMove(this, currentTurn, selectedRow, selectedCol);
}
//보드 초기화
public void ResetBoard()
{
Array.Clear(_board, 0, _board.Length);
}
private void SetState(Enums.PlayerType player)
public void SetState(BasePlayerState state)
{
currentTurn = player;
_stoneController.OnStoneClickedDelegate = (row, col) =>
_currentPlayerState?.OnExit(this);
_currentPlayerState = state;
_currentPlayerState?.OnEnter(this);
}
//스톤의 상태변경 명령함수
public void SetStoneNewState(Enums.StoneState state, int row, int col)
{
stoneController.SetStoneState(state, row, col);
}
public void SetStoneSelectedState(int row, int col)
{
if (_board[row, col] != Enums.PlayerType.None) return;
if (stoneController.GetStoneState(row, col) != Enums.StoneState.None && currentTurn == Enums.PlayerType.PlayerA) return;
//첫수 및 중복 확인
if ((selectedRow != row || selectedCol != col) && (selectedRow != -1 && selectedCol != -1))
{
if (_board[row, col] == Enums.PlayerType.None)
{
if ((selectedRow != row || selectedCol != col) && (selectedRow != -1 && selectedCol != -1))
{
SetStoneNewState(Enums.StoneState.None,selectedRow, selectedCol);
}
selectedRow = row;
selectedCol = col;
SetStoneNewState(Enums.StoneState.Selected, row, col);
}
};
stoneController.SetStoneState(Enums.StoneState.None,selectedRow, selectedCol);
}
selectedRow = row;
selectedCol = col;
stoneController.SetStoneState(Enums.StoneState.Selected, row, col);
}
//보드에 돌추가 함수
public void SetNewBoardValue(Enums.PlayerType playerType, int row, int col)
{
if (_board[row, col] == Enums.PlayerType.None)
if (_board[row, col] != Enums.PlayerType.None) return;
switch (playerType)
{
if (playerType == Enums.PlayerType.PlayerA)
{
_stoneController.SetStoneType(Enums.StoneType.Black, row, col);
_stoneController.SetStoneState(Enums.StoneState.LastPositioned, row, col);
case Enums.PlayerType.PlayerA:
stoneController.SetStoneType(Enums.StoneType.Black, row, col);
stoneController.SetStoneState(Enums.StoneState.LastPositioned, row, col);
_board[row, col] = Enums.PlayerType.PlayerA;
LastNSelectedSetting(row, col);
SetState(Enums.PlayerType.PlayerB);
ReplayManager.Instance.RecordStonePlaced(Enums.StoneType.Black, row, col); //기보 데이터 저장
}
if (playerType == Enums.PlayerType.PlayerB)
{
_stoneController.SetStoneType(Enums.StoneType.White, row, col);
_stoneController.SetStoneState(Enums.StoneState.LastPositioned, row, col);
break;
case Enums.PlayerType.PlayerB:
stoneController.SetStoneType(Enums.StoneType.White, row, col);
stoneController.SetStoneState(Enums.StoneState.LastPositioned, row, col);
_board[row, col] = Enums.PlayerType.PlayerB;
LastNSelectedSetting(row, col);
SetState(Enums.PlayerType.PlayerA);
ReplayManager.Instance.RecordStonePlaced(Enums.StoneType.White, row, col);
}
break;
}
}
//돌 지우는 함수
public void RemoveStone(int row, int col)
{
_board[row, col] = Enums.PlayerType.None;
stoneController.SetStoneType(Enums.StoneType.None, row, col);
stoneController.SetStoneState(Enums.StoneState.None, row, col);
}
//마지막 좌표와 선택 좌표 세팅
private void LastNSelectedSetting(int row, int col)
{
//첫수 확인
if (lastRow != -1 || lastCol != -1)
if (_lastRow != -1 || _lastCol != -1)
{
_stoneController.SetStoneState(Enums.StoneState.None, lastRow, lastCol);
stoneController.SetStoneState(Enums.StoneState.None, _lastRow, _lastCol);
}
//마지막 좌표 저장
lastRow = row;
lastCol = col;
_lastRow = row;
_lastCol = col;
//선택 좌표 초기화
selectedRow = -1;
selectedCol = -1;
}
//스톤의 상태변경 명령함수
private void SetStoneNewState(Enums.StoneState state, int row, int col)
//게임 끝
public void EndGame()
{
_stoneController.SetStoneState(state, row, col);
SetState(null);
}
//승리 확인 함수
public bool CheckGameWin(Enums.PlayerType player, int row, int col)
{
foreach (var dir in _directions)
{
var (count, _) = CountStones(_board, row, col, dir, player);
// 자기 자신 포함하여 5개 이상일 시 true 반환
if (count + 1 >= WIN_COUNT)
return true;
}
return false;
}
// 특정 방향으로 같은 돌 개수와 열린 끝 개수를 계산하는 함수
private (int count, int openEnds) CountStones(
Enums.PlayerType[,] board, int row, int col, int[] direction, Enums.PlayerType player)
{
int size = board.GetLength(0);
int count = 0;
int openEnds = 0;
// 정방향 탐색
int r = row + direction[0], c = col + direction[1];
while (r >= 0 && r < size && c >= 0 && c < size && board[r, c] == player)
{
count++;
r += direction[0]; // row값 옮기기
c += direction[1]; // col값 옮기기
}
if (r >= 0 && r < size && c >= 0 && c < size && board[r, c] == Enums.PlayerType.None)
{
openEnds++;
}
// 역방향 탐색
r = row - direction[0];
c = col - direction[1];
while (r >= 0 && r < size && c >= 0 && c < size && board[r, c] == player)
{
count++;
r -= direction[0];
c -= direction[1];
}
if (r >= 0 && r < size && c >= 0 && c < size && board[r, c] == Enums.PlayerType.None)
{
openEnds++;
}
return (count, openEnds);
}
}

View File

@ -19,6 +19,7 @@ public class GameManager : Singleton<GameManager>
private UserManager _userManager; // UserManager 인스턴스 관리
private CoinsPanelController _coinsPanel;
private Enums.GameType _gameType;
private GameLogic _gameLogic;
private StoneController _stoneController;
@ -33,10 +34,9 @@ public class GameManager : Singleton<GameManager>
{
GameObject userManagerObj = new GameObject("UserManager");
_userManager = userManagerObj.AddComponent<UserManager>();
//게임 씬에서 확인하기 위한 임시 코드
// _gameType = Enums.GameType.SinglePlay;
}
//게임 씬에서 확인하기 위한 임시 코드
_gameType = Enums.GameType.SinglePlay;
}
private void Start()
@ -44,12 +44,14 @@ public class GameManager : Singleton<GameManager>
// TODO: 로딩 화면 추가(자동 로그인 응답 전까지)
// 자동 로그인
TryAutoSignin();
// TryAutoSignin();
//게임 씬에서 확인하기 위한 임시 코드
// _stoneController = GameObject.FindObjectOfType<StoneController>();
// _stoneController.InitStones();
// _gameLogic = new GameLogic(_stoneController, _gameType);
_canvas = canvas.GetComponent<Canvas>();
_stoneController = GameObject.FindObjectOfType<StoneController>();
_stoneController.InitStones();
var fioTimer = FindObjectOfType<FioTimer>();
_gameLogic = new GameLogic(_stoneController, _gameType, fioTimer);
}
private void TryAutoSignin()
@ -119,7 +121,15 @@ public class GameManager : Singleton<GameManager>
public void OnClickConfirmButton()
{
_gameLogic.SetNewBoardValue(_gameLogic.currentTurn, _gameLogic.selectedRow,_gameLogic.selectedCol);
if (_gameLogic.selectedRow != -1 && _gameLogic.selectedCol != -1)
{
_gameLogic.OnConfirm();
}
else
{
Debug.Log("착수 위치를 선택 해주세요");
//TODO: 착수할 위치를 선택하라는 동작
}
}
private void ChangeToGameScene(Enums.GameType gameType)
@ -132,13 +142,24 @@ public class GameManager : Singleton<GameManager>
{
if (scene.name == "Game")
{
if (_gameType == Enums.GameType.Replay)
{
//TODO: 리플레이를 위한 초기화
}
_stoneController = GameObject.FindObjectOfType<StoneController>();
_stoneController.InitStones();
_gameLogic = new GameLogic(_stoneController, _gameType);
var fioTimer = FindObjectOfType<FioTimer>();
_gameLogic = new GameLogic(_stoneController, _gameType, fioTimer);
}
_canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
}
//임시 재시작 재대결
public void RetryGame()
{
_gameLogic.ResetBoard();
_stoneController.InitStones();
_gameLogic.SetState(_gameLogic.firstPlayerState);
}
public void OpenConfirmPanel(string message, ConfirmPanelController.OnConfirmButtonClick onConfirmButtonClick)
{
if (_canvas != null)

View File

@ -13,6 +13,7 @@ public class Stone : MonoBehaviour
private SpriteRenderer _spriteRenderer;
public delegate void OnStoneClicked(int index);
private OnStoneClicked _onStoneClicked;
private Enums.StoneState _currentStoneState;
private void Awake()
@ -52,20 +53,30 @@ public class Stone : MonoBehaviour
switch (stoneState)
{
case Enums.StoneState.None:
_currentStoneState = Enums.StoneState.None;
_spriteRenderer.sprite = stoneStateSprites[0];
break;
case Enums.StoneState.Selected:
_currentStoneState = Enums.StoneState.Selected;
_spriteRenderer.sprite = stoneStateSprites[1];
break;
case Enums.StoneState.Blocked:
_currentStoneState = Enums.StoneState.Blocked;
_spriteRenderer.sprite = stoneStateSprites[2];
break;
case Enums.StoneState.LastPositioned:
_currentStoneState = Enums.StoneState.LastPositioned;
_spriteRenderer.sprite = stoneStateSprites[3];
break;
}
}
//Stone 상태 확인
public Enums.StoneState GetStoneState()
{
return _currentStoneState;
}
private void OnMouseUpAsButton()
{
_onStoneClicked?.Invoke(_index);

View File

@ -27,7 +27,6 @@ public class StoneController : MonoBehaviour
//스톤 타입변경
public void SetStoneType(Enums.StoneType stoneType, int row, int col)
{
var index = MaxCellCount * row + col;
stones[index].SetStone(stoneType);
}
@ -38,4 +37,11 @@ public class StoneController : MonoBehaviour
var index = MaxCellCount * row + col;
stones[index].SetState(state);
}
//스톤상태 확인
public Enums.StoneState GetStoneState(int row, int col)
{
var index = MaxCellCount * row + col;
return stones[index].GetStoneState();
}
}