我寫了一個簡單的控制臺游戲(具體來說是井字游戲)來練習。游戲結束后,我需要重置游戲,因此我正在創建游戲類的新實體。
類的舊實體在創建新實體之前是否已銷毀?
如果不是,那么它會堆積在記憶體中,這不好。那么這里更好的做法是什么?
//main class
using System;
namespace TicTacToe
{
internal class Program
{
static void Main(string[] args)
{
bool restart = true; //stores decision whether to restart the game
do
{
Game game = new Game(); //a simple console game
game.start(); //start -> play -> game over
restart = playAgain(); //playAgain returns a boolean
} while (restart);
}
public static bool playAgain()
{
Console.WriteLine("Do you want to play again? (y/N): ");
string input = Console.ReadLine();
if (input == "y" || input == "Y")
return true;
else return false;
}
}
}
//game class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TicTacToe
{
internal class Game
{
string[] values = new string[9] { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
bool gameOver;
int turns;
public Game()
{
this.turns = 0;
this.gameOver = false;
}
public void displayGameCard()
{
Console.Clear();
Console.WriteLine( " | | ");
Console.WriteLine($" {values[0]} | {values[1]} | {values[2]} ");
Console.WriteLine("_____|_____|_____");
Console.WriteLine(" | | ");
Console.WriteLine($" {values[3]} | {values[4]} | {values[5]} ");
Console.WriteLine("_____|_____|_____");
Console.WriteLine(" | | ");
Console.WriteLine($" {values[6]} | {values[7]} | {values[8]} ");
Console.WriteLine(" | | ");
//Console.WriteLine("-----------");
}
public void player1()
{
string strInput;
int index;
bool flag = true;
do
{
Console.Write("\nPlayer 1: ");
strInput = Console.ReadLine();
if (values.Contains(strInput) && strInput != "O" && strInput != "X")
{
flag = false;
}
else Console.WriteLine("Invalid Input! Try Again!");
} while (flag == true);
this.turns ;
index = int.Parse(strInput) - 1;
values[index] = "O";
displayGameCard();
this.gameOver = checkResult();
}
public void player2()
{
string strInput;
int index;
bool flag = true;
do
{
Console.Write("\nPlayer 2: ");
strInput = Console.ReadLine();
if (values.Contains(strInput) && strInput != "O" && strInput != "X")
{
flag = false;
}
else Console.WriteLine("Invalid Input! Try Again!");
} while (flag == true);
this.turns ;
index = int.Parse(strInput) - 1;
values[index] = "X";
displayGameCard();
this.gameOver = checkResult();
}
public bool checkResult()
{
bool flag = false;
if (values[0] == values[1] && values[1] == values[2])
flag = true;
else if (values[3] == values[4] && values[4] == values[5])
flag = true;
else if (values[6] == values[7] && values[7] == values[8])
flag = true;
else if (values[0] == values[3] && values[3] == values[6])
flag = true;
else if (values[1] == values[4] && values[4] == values[7])
flag = true;
else if (values[2] == values[5] && values[5] == values[8])
flag = true;
else if (values[0] == values[4] && values[4] == values[8])
flag = true;
else if (values[2] == values[4] && values[4] == values[6])
flag = true;
return flag;
}
public void play()
{
displayGameCard();
player1();
if (this.turns == 9)
{
Console.WriteLine("It's a draw!");
this.gameOver = true;
}
else if (this.gameOver)
{
Console.WriteLine("Player 1 won!");
}
else
{
player2();
if (this.gameOver)
Console.WriteLine("Player 2 won!");
}
}
public void start()
{
do
{
play();
} while (this.gameOver == false);
}
}
}
如果相關,代碼是用 c# 撰寫的。
uj5u.com熱心網友回復:
據我所知(因為我對此比較陌生)您在 do 范圍內宣告的所有變數都是本地的,并且當程式超出該范圍時,這些變數將被銷毀。因此,您在 do 范圍內宣告的游戲類的實體是本地的,因此當 while 回圈再次檢查條件時將被銷毀。
uj5u.com熱心網友回復:
當您創建一個名為 Game 類的新實體時,game您所做的就是將變數設定game為一個新實體。game保存在記憶體中,因此下次啟動游戲時,它將獲取變數game,并且無論它處于什么狀態,都會將其設定為新實體。這意味著該類的實體永遠不會超過一次,無論它是否在 do/while 回圈中,因為您使用的是相同的變數。
uj5u.com熱心網友回復:
簡短版本:
我應該在回圈內宣告并創建一個類的實體嗎?
是的,如果您只需要回圈內的那個實體。
當我們創建一個物件
Game game = new Game();
...只要有對它的參考,它就“存在”在記憶體中。當不再有對物件的任何參考時,它就可用于垃圾收集。
所以問題是,對創建的Game物件有哪些參考?似乎只有一個參考,game即您分配給它的變數。
所以現在的問題是,這個變數能活多久?它的存在時間與定義它的范圍一樣長。在這種情況下,您將在do回圈中定義它。一旦回圈的執行結束(幾行之后),變數就會超出范圍。換句話說,定義它的范圍不再存在。簡而言之,該變數不再存在。
該變數是對該確切Game物件的唯一參考。當變數超出范圍時,不再有對該Game物件的任何參考。它將被垃圾收集。(這不會立即發生,但我們不必擔心它何時發生。我們通常不在乎。這是框架為我們擔心的事情。)
如果回圈重復怎么辦?將該回圈的內部視為一個被反復呼叫的方法。當它再次被呼叫時,game變數是新的,因為它是在回圈中宣告的。Game它對回圈的先前執行或先前物件一無所知。該變數在回圈迭代結束時超出范圍。
我們如何判斷變數的作用域是什么?一種簡單的方法是查看我們可以在哪里使用它。
如果您嘗試撰寫此代碼,請game在回圈外使用變數:
static void Main(string[] args)
{
bool restart = true; //stores decision whether to restart the game
do
{
Game game = new Game(); //a simple console game
game.start(); //start -> play -> game over
restart = playAgain(); //playAgain returns a boolean
} while (restart);
}
game.Start(); // <-- Outside the loop where it was declared
...它不會編譯。那是因為變數是在回圈內宣告的,所以它在回圈外不可用。就像我們在一個方法中宣告一個區域變數一樣,它在另一個方法中是不可見或不可訪問的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/457127.html
下一篇:物件內部的變數不會公開更改
