1. Undo 와 Redo


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



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
//  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 메뉴의 이벤트 핸들러 코드를 생성하고 아래와 같이 수정한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//
//  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()를 다음과 같이 수정한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//
//  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를 선택한다.



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



1
using Microsoft.VisualBasic.Devices;



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



1
2
3
4
5
6
7
8
9
10
11
12
13
//
//  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 메뉴의 이벤트 핸들러를 생성하고 아래와 같이 수정한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
//
//  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 메뉴의 이벤트 핸들러는 다음과 같다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//
//  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 메뉴의 이벤트 핸들러는 다음과 같다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//
//  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 쿨한넘