/// <summary> /// この手牌でチーできるか /// </summary> /// <param name="tile">チーできるか調べる牌</param> /// <returns>チーできるか</returns> public bool CanChow(TileNames tile) { if (TileNames.East <= tile) { return(false); } int i = (int)tile % 10; bool flag = false; if (!flag && 1 <= i && i <= 7) { flag = (tiletypes[i + 1] > 0 && tiletypes[i + 2] > 0); } if (!flag && 2 <= i && i <= 8) { flag = (tiletypes[i - 1] > 0 && tiletypes[i + 1] > 0); } if (!flag && 3 <= i && i <= 9) { flag = (tiletypes[i - 2] > 0 && tiletypes[i - 1] > 0); } return(flag); }
/// <summary> /// 牌を1枚捨てる /// </summary> /// <param name="tile">捨てる牌</param> public void DiscarTile(TileNames tile) { // 自摸牌分追加する tiletypes[(int)LastTile]++; LastTile = TileNames.Null; tiletypes[(int)tile]--; }
/// <summary> /// 牌を打つ /// </summary> /// <param name="tile">打牌する牌</param> public void RemoveTile(TileNames tile) { // 河に追加 DiscTiles.AddTile(tile); // 打牌 Hands.DiscarTile(tile); }
/// <summary> /// 自摸する /// </summary> /// <param name="tile">自摸する牌</param> public void SetTile(TileNames tile) { if (LastTile != TileNames.Null) { throw new ArgumentException("打牌される前に自摸されています。"); } LastTile = tile; }
/// <summary> /// 順子が含まれるか /// </summary> /// <param name="tile">順子の一番前の牌</param> /// <returns>含まれるか</returns> bool ContainsChow(TileNames tile) { int index = (int)tile; // 数牌の種類を超えての順子判定は、番号を種類ごとに一つ飛ばして割り振ってあるため起こらない return (index <= (int)TileNames.East && (tiletypes[index] >= 1 && tiletypes[index + 1] >= 1 && tiletypes[index + 2] >= 1)); }
/// <summary> /// 表ドラをすべて取得する /// </summary> /// <returns>すべての表ドラ</returns> public TileNames[] GetAllFrontDoras() { TileNames[] doras = new TileNames[4]; for (int i = 0; i < 4; i++) { doras[i] = tiles[i + 124]; } return(doras); }
/// <summary> /// 洗牌 /// </summary> void Shuffing() { Random rand; for (int i = 0; i < tiles.Length; i++) { rand = new Random(i + DateTime.Now.Millisecond); int num = rand.Next(136); // swap TileNames tmp = tiles[i]; tiles[i] = tiles[num]; tiles[num] = tmp; } }
public void AddTile(TileNames tile) { tiles.Add(new KeyValuePair <TileNames, TileStatus>(tile, TileStatus.Normal)); }
public override void onPlayerCommand(PlayerCommandEvent Event) { int player = ((Player)Event.Sender).whoAmi; string command = Event.Message; string[] split = command.Split(' '); split[0] = split[0].ToLower(); var sender = Event.Sender; if (split[0] == "//pos1" || split[0] == "//p1") { Event.Cancelled = true; if (!PermissionManager.HasPermission(player, "terraedit.selection")) { sender.sendMessage("You don't have enough permissions!"); return; } if (!Waiting1.ContainsKey(player)) { Waiting1.Add(player, true); } if (!Waiting2.ContainsKey(player)) { Waiting2.Add(player, false); } Waiting1[player] = true; Waiting2[player] = false; sender.sendMessage("Waiting for block place/destroy."); return; } if (split[0] == "//pos2" || split[0] == "//p2") { Event.Cancelled = true; if (!PermissionManager.HasPermission(player, "terraedit.selection")) { sender.sendMessage("You don't have enough permissions!"); return; } if (!Waiting1.ContainsKey(player)) { Waiting1.Add(player, false); } if (!Waiting2.ContainsKey(player)) { Waiting2.Add(player, true); } Waiting2[player] = true; Waiting1[player] = false; sender.sendMessage("Waiting for block place/destroy."); return; } if (split[0] == "//set") { Event.Cancelled = true; if (!PermissionManager.HasPermission(player, "terraedit.set")) { sender.sendMessage("You don't have enough permissions!"); return; } if (split.Length < 2) { sender.sendMessage("USAGE: //set [block]"); return; } if (!SelectionMade(player)) { sender.sendMessage("You haven't made a selection!"); return; } int id; if (!Int32.TryParse(split[1], out id)) { id = TileNames.FindTileByName(split[1]); if (id == -2) { sender.sendMessage("Invalid block name!"); return; } } if (id < -1 || id > 79) { sender.sendMessage("Invalid block ID!"); return; } //var tile = new Tile {type = Byte.Parse(split[1])}; var action = new Action(); int highX = Pos1[player].X > Pos2[player].X ? (int)Pos1[player].X : (int)Pos2[player].X; int highY = Pos1[player].Y > Pos2[player].Y ? (int)Pos1[player].Y : (int)Pos2[player].Y; int lowX = Pos1[player].X < Pos2[player].X ? (int)Pos1[player].X : (int)Pos2[player].X; int lowY = Pos1[player].Y < Pos2[player].Y ? (int)Pos1[player].Y : (int)Pos2[player].Y; for (int i = lowX; i <= highX; i++) { for (int j = lowY; j <= highY; j++) { action.SetBlock(i, j, id); } } int c = action.Do(); if (!Actions.ContainsKey(player)) { Actions.Add(player, new List <Action>()); } if (Actions[player].Count > 0) { Actions[player].Insert(0, action); } else { Actions[player].Add(action); } sender.sendMessage(c + " blocks modified."); return; } if (split[0] == "//disc") { Event.Cancelled = true; if (!PermissionManager.HasPermission(player, "terraedit.disc")) { sender.sendMessage("You don't have enough permissions!"); return; } if (split.Length < 3) { sender.sendMessage("USAGE: //disc [radius] [block]"); return; } if (!Pos1.ContainsKey(player) || Pos1[player] == null) { sender.sendMessage("You must set position 1 as the circle center!"); return; } int radius; if (!Int32.TryParse(split[1], out radius)) { sender.sendMessage("Invalid radius!"); return; } if (radius < 1) { sender.sendMessage("Radius must be higher than 0!"); return; } int id; if (!Int32.TryParse(split[2], out id)) { id = TileNames.FindTileByName(split[2]); if (id == -2) { sender.sendMessage("Invalid block name!"); return; } } if (id < -1 || id > 79) { sender.sendMessage("Invalid block ID!"); return; } var action = new Action(); int px = Convert.ToInt32(Pos1[player].X); int py = Convert.ToInt32(Pos1[player].Y); for (int i = px - radius; i <= px + radius; i++) { for (int j = py - radius; j <= py + radius; j++) { if ((px - i) * (px - i) + (py - j) * (py - j) < radius * radius) { action.SetBlock(i, j, id); } } } int c = action.Do(); if (!Actions.ContainsKey(player)) { Actions.Add(player, new List <Action>()); } if (Actions[player].Count > 0) { Actions[player].Insert(0, action); } else { Actions[player].Add(action); } sender.sendMessage(c + " blocks modified."); return; } if (split[0] == "//replace") { Event.Cancelled = true; if (!PermissionManager.HasPermission(player, "terraedit.replace")) { sender.sendMessage("You don't have enough permissions!"); return; } if (split.Length < 3) { sender.sendMessage("USAGE: //replace [from] [to]"); return; } if (!SelectionMade(player)) { sender.sendMessage("You haven't made a selection!"); return; } int from; if (!Int32.TryParse(split[1], out from)) { from = TileNames.FindTileByName(split[1]); if (from == -2) { sender.sendMessage("Invalid block name!"); return; } } if (from < -1 || from > 79) { sender.sendMessage("Invalid block ID!"); return; } int to; if (!Int32.TryParse(split[2], out to)) { to = TileNames.FindTileByName(split[2]); if (to == -2) { sender.sendMessage("Invalid block name!"); return; } } if (to < -1 || to > 79) { sender.sendMessage("Invalid block ID!"); return; } var action = new Action(); int highX = Pos1[player].X > Pos2[player].X ? (int)Pos1[player].X : (int)Pos2[player].X; int highY = Pos1[player].Y > Pos2[player].Y ? (int)Pos1[player].Y : (int)Pos2[player].Y; int lowX = Pos1[player].X < Pos2[player].X ? (int)Pos1[player].X : (int)Pos2[player].X; int lowY = Pos1[player].Y < Pos2[player].Y ? (int)Pos1[player].Y : (int)Pos2[player].Y; for (int i = lowX; i <= highX; i++) { for (int j = lowY; j <= highY; j++) { if (Main.tile.At(i, j).Type == from) { action.SetBlock(i, j, to); } } } int c = action.Do(); if (!Actions.ContainsKey(player)) { Actions.Add(player, new List <Action>()); } if (Actions[player].Count > 0) { Actions[player].Insert(0, action); } else { Actions[player].Add(action); } sender.sendMessage(c + " blocks modified."); return; } if (split[0] == "//undo") { Event.Cancelled = true; if (!PermissionManager.HasPermission(player, "terraedit.undo")) { sender.sendMessage("You don't have enough permissions!"); return; } if (Actions[player].Count == 0) { sender.sendMessage("Nothing to undo!"); return; } foreach (KeyValuePair <Vector2, ActionBlock> kvp in Actions[player].First().changedBlocks) { int X = Convert.ToInt32(kvp.Key.X); int Y = Convert.ToInt32(kvp.Key.Y); //World world = Program.server.getWorld(); if (kvp.Value.StartType == -1) { Main.tile.At(X, Y).SetActive(false); NetMessage.SendTileSquare(-1, X, Y, 1); } else { /*WorldGen.KillTile(X, Y, world, false, false, true); * WorldGen.PlaceTile(X, Y, world, kvp.Value.StartType, false, true);*/ Main.tile.At(X, Y).SetActive(true); Main.tile.At(X, Y).SetType((byte)kvp.Value.StartType); NetMessage.SendTileSquare(-1, X, Y, 1); } } Actions[player].Remove(Actions[player].First()); sender.sendMessage("Last action undone"); return; } return; }
/// <summary> /// この手牌でカンできるか /// </summary> /// <param name="tile">カンできるか調べる牌</param> /// <returns>カンできるか</returns> public bool CanKan(TileNames tile) { return(tiletypes[(int)tile] >= 3); }
/// <summary> /// この手牌でポンできるか /// </summary> /// <param name="tile">ポンできるか調べる牌</param> /// <returns>ポンできるか</returns> public bool CanPon(TileNames tile) { return(tiletypes[(int)tile] >= 2); }
/// <summary> /// 東風戦のメイン /// </summary> /// <returns>一局終了するとEndPhaseを投げる</returns> protected override Phase update() { // Debug string[] ps = { "東", "南", "西", "北" }; // アクティブなプレイヤー DX.DrawString(0, 450, ps[PlayerNum], DX.GetColor(255, 255, 255)); // ツモ牌表示 DX.DrawGraph(687, PlayerNum * 80 - ((keytiles.LastKeyPressed()) ? 10 : 0), Mahjong.TileHandle[(int)players[PlayerNum].Hands.LastTile], 1); // 各プレイヤー for (int i = 0; i < 4; i++) { // 家を表示 DX.DrawString(0, i * 82, ps[(int)players[i].Status], DX.GetColor(255, 255, 255)); // 手牌を表示 int j = 0; foreach (var tile in players[i].Hands.GetAllTiles()) { DX.DrawGraph(50 + j * 49, i * 80 - ((keytiles.pressed[j] && PlayerNum == i) ? 10 : 0), Mahjong.TileHandle[(int)tile], 1); j++; } // キー名を表示 j = 0; foreach (string keyname in keytiles.tilekeys_name) { DX.DrawString(55 + j * 49, 350, keyname, DX.GetColor(255, 255, 255)); j++; } // 河を表示 j = 0; foreach (var tile in players[i].DiscTiles.GetAllTiles()) { int x = 350 + j * 20; int y = 400 + i * 32; DX.DrawExtendGraph(x, y, x + 20, y + 32, Mahjong.TileHandle[(int)tile], 1); j++; } } // 山から何枚ツモされたか DX.DrawString(0, 500, walltiles.Count.ToString(), DX.GetColor(255, 255, 255)); // End Debug for (int i = 0; i < Mahjong.HandTileCount; i++) { if (keytiles.IsKeyByUpdate(key, i)) { TileNames lasttile = players[PlayerNum].GetTileNumberOf(i); // 川に捨てる players[PlayerNum].RemoveTile(lasttile); PlayerNum = (PlayerNum + 1) % 4; // 山からツモる players[PlayerNum].AddTile(walltiles.Drawing()); } } return(this); }
/// <summary> /// コンストラクター /// </summary> /// <param name="tile">基準となる牌</param> /// <param name="status">鳴いた種類</param> /// <param name="player">誰から鳴いたか</param> public TakenTile(TileNames tile, TakenTileStatus status, PlayerStatus player) { Tile = tile; Status = status; Player = player; }
/// <summary> /// 牌を1枚手牌に追加する /// </summary> /// <param name="tile">手牌に追加する牌</param> public void AddTile(TileNames tile) { Hands.SetTile(tile); }
/// <summary> /// /// </summary> /// <param name="index"></param> /// <returns></returns> public TileNames GetTileNumberOf(int index) { TileNames tile = Hands.GetTile(index); return(tile); }