1. Undo 와 Redo


움직임의 undo는 Moves stack에서 pop, 그리고 이를 RedoMoves stack에 push, 반대로 redo는 RedoMoves stack에서 pop, 이것을 Moves stack에 push 한다. 디자인 뷰에서 Edit -> Undo를 선택하고 더블클릭하여 이벤트 핸들러 코드를 생성하고 다음과 같이 수정한다.



		//
		//	undo a move
		//
		private void undoToolStripMenuItem_Click( object sender, EventArgs e )
		{
			//	if no previous moves, then exit
			if ( Moves.Count == 0 )
				return;

			//	remove from the Moves stack and push into the RedoMoves stack
			String str = Moves.Pop();
			RedoMoves.Push( str );

			//	save the value in the array
			SetCell( int.Parse( str.Substring( 0, 1 ) ), int.Parse( str.Substring( 1, 1 ) ), 0, 1 );
			DisplayActivity( "Value " + str[2] + " removed at (" + str[0] + ", " + str[1] + ")", false );
		}


마찬가지로 Redo 메뉴의 이벤트 핸들러 코드를 생성하고 아래와 같이 수정한다.



		//
		//	redo the move
		//
		private void redoToolStripMenuItem_Click( object sender, EventArgs e )
		{
			//	if RedoMove stack is empty, the exit
			if ( RedoMoves.Count == 0 )
				return;

			//	remove from the RedoMoves stack and push into the Moves stack
			String str = RedoMoves.Pop();
			Moves.Push( str );

			//	save the value in the array
			SetCell( int.Parse( str.Substring( 0, 1 ) ), int.Parse( str.Substring( 1, 1 ) ), int.Parse( str.Substring( 2, 1 ) ), 1 );
			DisplayActivity( "Value " + str[2] + " reinserted at (" + str[0] + ", " + str[1] + ")", false );
		}



2. 게임의 저장


퍼즐은 숫자로 이루어진 String으로 텍스트화일에 저장된다. SaveGameToDisk()를 다음과 같이 수정한다.



		//
		//	Save the game to disk
		//
		public void SaveGameToDisk( Boolean saveAs )
		{
			//	if saveFileName is empty, means game has not been saved before
			if ( ( saveFileName == String.Empty ) || saveAs )
			{
				SaveFileDialog saveFileDialog1 = new SaveFileDialog();

				saveFileDialog1.Filter = "SDO files (*.sdo)|*.sdo|All files (*.*)|*.*";
				saveFileDialog1.FilterIndex = 1;
				saveFileDialog1.RestoreDirectory = false;

				if ( saveFileDialog1.ShowDialog() == DialogResult.OK )
				{
					//	store the filename first
					saveFileName = saveFileDialog1.FileName;
				}
				else
				{
					return;
				}
			}

			//	formulate the string representing the values to store
			StringBuilder str = new StringBuilder();

			for ( int row = 1; row < 10; row++ )
				for ( int col = 1; col < 10; col++ )
					str.Append( actual[col, row].ToString() );

			//	save the values to file
			Computer myComputer = new Computer();

			try
			{
				Boolean fileExists;

				fileExists = myComputer.FileSystem.FileExists( saveFileName );

				if ( fileExists )
					myComputer.FileSystem.DeleteFile( saveFileName );

				myComputer.FileSystem.WriteAllText( saveFileName, str.ToString(), true );

				toolStripStatusLabel1.Text = "Puzzle saved in " + saveFileName;
			}
			catch ( Exception )
			{
				MessageBox.Show( "Error saving game. Please try again." );
				throw;
			}
		}



코드를 추가하면 Computer 클래스를 알지 못한다고 에러를 띄운다.

솔루션 익스플로러에서 Reference를 마우스 오른쪽 클릭하고 Add Reference 선택하여 .NET 탭에서 Microsoft.VisualBasic를 선택한다.



그리고 코드 맨 위에 아래 코드를 추가한다.



using Microsoft.VisualBasic.Devices;



File->Save As... 메뉴의 이벤트 핸들러를 생성하고 아래와 같이 수정한다.



		//
		//	Save As... menu item
		//
		private void saveAsToolStripMenuItem_Click( object sender, EventArgs e )
		{
			if ( !GameStarted )
			{
				DisplayActivity( "Game not started yet.", true );
				return;
			}

			SaveGameToDisk( true );
		}


File->Save 메뉴의 이벤트 핸들러를 생성하고 아래와 같이 수정한다.



		//
		//	Save menu item
		//
		private void saveToolStripMenuItem_Click( object sender, EventArgs e )
		{
			if ( !GameStarted )
			{
				DisplayActivity( "Game not started yet.", true );
				return;
			}

			SaveGameToDisk( false );
		}



3. 저장된 게임 열기


File->Open 메뉴의 이벤트 핸들러는 다음과 같다.



		//
		//	Open a saved game
		//
		private void openToolStripMenuItem_Click( object sender, EventArgs e )
		{
			if ( GameStarted )
			{
				var response = MessageBox.Show( "Do you want to save current game?",
												"Save current game",
												MessageBoxButtons.YesNoCancel,
												MessageBoxIcon.Question );

				if ( response == DialogResult.Yes )
					SaveGameToDisk( false );
				else if ( response == DialogResult.Cancel )
					return;

			}

			//	load the game from disk

			String fileContents;
			OpenFileDialog openFileDialog1 = new OpenFileDialog();
			Computer myComputer = new Computer();

			openFileDialog1.Filter = "SDO files (*.sdo)|*.sdo|All files (*.*)|*.*";
			openFileDialog1.FilterIndex = 1;
			openFileDialog1.RestoreDirectory = false;

			if ( openFileDialog1.ShowDialog() == DialogResult.OK )
			{
				fileContents = myComputer.FileSystem.ReadAllText( openFileDialog1.FileName );
				toolStripStatusLabel1.Text = openFileDialog1.FileName;
				saveFileName = openFileDialog1.FileName;
			}
			else
			{
				return;
			}

			StartNewGame();

			//	initialize the board

			int counter = 0;
			int value;

			for ( int row = 1; row < 10; row++ )
			{
				for ( int col = 1; col < 10; col++ )
				{
					try
					{
						value = int.Parse( fileContents[counter].ToString() );

						if ( value != 0 )
							SetCell( col, row, value, 0 );
					}
					catch ( Exception )
					{
						MessageBox.Show( "File does not contain a valid Sudoku puzzle" );

						throw;
					}

					counter++;
				}
			}

		}


4. 게임 종료


File -> Exit 메뉴의 이벤트 핸들러는 다음과 같다.



		//
		//	Exit the application
		//
		private void exitToolStripMenuItem_Click( object sender, EventArgs e )
		{

			if ( GameStarted )
			{
				DialogResult reponse = MessageBox.Show( "Do you want to save current game?",
														"Save current game",
														MessageBoxButtons.YesNoCancel );

				if ( reponse == DialogResult.Yes )
					SaveGameToDisk( false );
				else if ( reponse == DialogResult.Cancel )
					return;

			}

			this.Close();
			Application.Exit();
		}




Posted by 쿨한넘