1. 程式人生 > >學以致用——Java原始碼——海龜繪圖小程式2018版(Turtles Graphics)

學以致用——Java原始碼——海龜繪圖小程式2018版(Turtles Graphics)

程式功能:

支援使用者在畫板上按以下繪圖指令繪製軌跡(類似於小海龜在畫板上按東、南、西、北方向行走時形成的任意軌跡):
1:擡起畫筆
2:落下畫筆
3:右轉
4:左轉
5:畫筆向前移動n步(第一次移動時預設為向右移動,n為自定義)
6:繪製圖形
7:擦除圖形
9:退出程式

參考文章:

簡單的海龜繪圖語言(Design a Turtle Graphics language which can be used to draw "L" graphics),

https://blog.csdn.net/hpdlzu80100/article/details/2312204

執行效果示例:

輔助工具:

Excel中使用條件格式化,可以快速設計要使用海龜繪圖語言(本程式)繪製的圖形,並可幫助我們輸入指令(前進方向,前進步數)。

執行過程示例:

********歡迎使用海龜繪圖語言********

 

請按照以下說明輸入繪圖指令:

1:擡起畫筆

2:落下畫筆

3:右轉

4:左轉

5:畫筆向前移動n步(第一次移動時預設為向右移動,n為自定義)

6:繪製圖形

7:擦除圖形

9:退出程式

 

指令(當前位置:【11】,當前朝向:東):5

請輸入移動步數:6

已向前移動6步,當前位置:【17】,當前朝向:東

指令(當前位置:【1,7】,當前朝向:東):3

朝向已更改為:南

指令(當前位置:【1,7】,當前朝向:南):5

請輸入移動步數:1

已向前移動1步,當前位置:[2,7],當前朝向:南

指令(當前位置:【2,7】,當前朝向:南):2

畫筆已落下。

指令(當前位置:【27】,當前朝向:南):4

朝向已更改為:東

指令(當前位置:【27】,當前朝向:東):5

請輸入移動步數:5

已向前移動5步,當前位置:【212】,當前朝向:東

指令(當前位置:【212】,當前朝向:東):3

朝向已更改為:南

指令(當前位置:【212】,當前朝向:南):5

請輸入移動步數:3

已向前移動3步,當前位置:[5,12],當前朝向:南

指令(當前位置:【5,12】,當前朝向:南):4

朝向已更改為:東

指令(當前位置:【5,12】,當前朝向:東):5

請輸入移動步數:4

已向前移動4步,當前位置:【516】,當前朝向:東

指令(當前位置:【516】,當前朝向:東):3

朝向已更改為:南

指令(當前位置:【516】,當前朝向:南):5

請輸入移動步數:6

已向前移動6步,當前位置:[11,16],當前朝向:南

指令(當前位置:【1116】,當前朝向:南):3

朝向已更改為:西

指令(當前位置:【1116】,當前朝向:西):5

請輸入移動步數:13

已向前移動13步,當前位置:[11,3],當前朝向:西

指令(當前位置:【113】,當前朝向:西):3

朝向已更改為:北

指令(當前位置:【113】,當前朝向:北):5

請輸入移動步數:6

已向前移動6步,當前位置:[5,3],當前朝向:北

指令(當前位置:【5,3】,當前朝向:北):3

朝向已更改為:東

指令(當前位置:【5,3】,當前朝向:東):5

請輸入移動步數:4

已向前移動4步,當前位置:【57】,當前朝向:東

指令(當前位置:【5,7】,當前朝向:東):3

朝向已更改為:南

指令(當前位置:【57】,當前朝向:南):3

朝向已更改為:西

指令(當前位置:【57】,當前朝向:西):3

朝向已更改為:北

指令(當前位置:【57】,當前朝向:北):5

請輸入移動步數:3

已向前移動3步,當前位置:[2,7],當前朝向:北

指令(當前位置:【27】,當前朝向:北):6

程式碼如下:

import java.util.Scanner;

//JHTP Exercise 7.10: Sales Commissions
//by [email protected]
/*7.21 (Turtle Graphics) The Logo language made the concept of turtle graphics famous. Imagine a mechanical
 *  turtle that walks around the room under the control of a Java application. The turtle holds a pen in one
 *   of two positions, up or down. While the pen is down, the turtle traces out shapes as it moves, and while
 *    the pen is up, the turtle moves about freely without writing anything. In this problem, you’ll simulate
 *     the operation of the turtle and create a computerized sketchpad.
Use a 20-by-20 array floor that’s initialized to zeros. Read commands from an array that contains them. 
Keep track of the current position of the turtle at all times and whether the pen is currently up or down. 
Assume that the turtle always starts at position (0, 0) of the floor with its pen up. The set of turtle commands
 your application must process are shown in Fig. 7.29.

Command -> Meaning
1 ->  Pen up
2  -> Pen down
3 ->  Turn right
4  -> Turn left
5,10 ->  Move forward 10 spaces (replace 10 for a different number of spaces)
6  -> Display the 20-by-20 array
9 ->  End of data (sentinel)

Suppose that the turtle is somewhere near the center of the floor. The following “program” would draw
 and display a 12-by-12 square, leaving the pen in the up position:
2
5,12
3
5,12
3
5,12
3
5,12
1
6
9
As the turtle moves with the pen down, set the appropriate elements of array floor to 1s. When the 6 
command (display the array) is given, wherever there’s a 1 in the array, display an asterisk or any 
character you choose. Wherever there’s a 0, display a blank.
Write an application to implement the turtle graphics capabilities discussed here. Write several turtle
 graphics programs to draw interesting shapes. Add other commands to increase the power of your turtle 
 graphics language.*/

public class TurtleGraphics  {
	
	//private static int commands[]={1,5,2,5,3,5,4,5,3,5,5,3,5,5,5,3,5,5,3,5,4,5,1,6,9}; //繪製“凸”字形
	//private static int commands[]={2,5,12,3,5,12,3,5,12,3,5,12,1,6,9}; //繪製“凸”字形
	private static int pace=5;
	private static int[][] positions = new int[20][20];
	private static int row,column;
	private static boolean penLocation;	//畫筆位置(擡起或落下,預設為擡起)
	private static String currentDirection = "東";	//初始朝向為東
	private static boolean moveLeft,moveRight,moveDownwards,moveUpwards; 	//畫筆移動方向(東、南、西、北)
	private static int instruction;	//使用者輸入的單條指令
	private static Scanner input = new Scanner(System.in);
 
 public static void main(String[] args)
 {   
     row=0;
     column=0;
     moveRight=true;
     
     System.out.println("********歡迎使用海龜繪圖語言********");   
     System.out.printf("%n請按照以下說明輸入繪圖指令:%n"
     		+ "1:擡起畫筆%n"
     		+ "2:落下畫筆%n"
     		+ "3:右轉%n"
     		+ "4:左轉%n"
     		+ "5:畫筆向前移動n步(第一次移動時預設為向右移動,n為自定義)%n"
     		+ "6:繪製圖形%n"
     		+ "7:擦除圖形%n"
     		+ "9:退出程式%n%n");
     do {
	 System.out.printf("指令(當前位置:【%d,%d】,當前朝向:%s):",row+1, column+1, currentDirection);
	 instruction =input.nextInt();
	 if (instruction == 5) {
		 System.out.printf("請輸入移動步數:");
	 pace =input.nextInt();
	 turtleBehaviour(instruction);	//如果指令是5,先設定步長,再執行前移動作
	 continue;
	 }
	 else turtleBehaviour(instruction);
		} while (instruction != 9);  


 }
 
 public static void turtleBehaviour(int argument)
 {
     switch (argument)
     {
     case 1:	//擡起畫筆
         penLocation=false;
         System.out.println("畫筆已擡起。");
         break;
     case 2:	//落下畫筆
         penLocation=true;
         System.out.println("畫筆已落下。");
         break;
     case 3:// 右轉
         if (moveRight)  //如果當前移動方向是右移,則右轉向後移動方向變為向下移動
         {
             moveDownwards=true;	//向下移動為true
             moveLeft=moveRight=moveUpwards=false;	//其他移動方向為false
             currentDirection="南";
             System.out.printf("朝向已更改為:%s%n",currentDirection);
         }
         else if(moveLeft)	//如果當前移動方向是左移,則右轉向後移動方向變為向上移動
         {
             moveUpwards=true;
             moveLeft=moveRight=moveDownwards=false;
             currentDirection="北";
             System.out.printf("朝向已更改為:%s%n",currentDirection);
         }
         else if(moveUpwards)	//如果當前移動方向是上移,則右轉向後移動方向變為向右移動
         {
            moveRight=true;
             moveLeft=moveUpwards=moveDownwards=false;
             currentDirection="東";
             System.out.printf("朝向已更改為:%s%n",currentDirection);
         }
         else if(moveDownwards)	//如果當前移動方向是下移,則右轉向後移動方向變為向左移動
         {
             moveLeft=true;
             moveUpwards=moveRight=moveDownwards=false;
             currentDirection="西";
             System.out.printf("朝向已更改為:%s%n",currentDirection);
         }
         
         break;
     case 4:// 左轉
         if (moveRight)
         {
             moveUpwards=true;
             moveLeft=moveRight=moveDownwards=false;
             currentDirection="北";
             System.out.printf("朝向已更改為:%s%n",currentDirection);
         }
         else if(moveLeft)
         {
             moveDownwards=true;
             moveLeft=moveRight=moveUpwards=false;
             currentDirection="南";
             System.out.printf("朝向已更改為:%s%n",currentDirection);
             
         }
         else if(moveUpwards)
       {
             moveLeft=true;
             moveRight=moveUpwards=moveDownwards=false;
             currentDirection="西";
             System.out.printf("朝向已更改為:%s%n",currentDirection);;
         }
         else if(moveDownwards)
         {
             moveRight=true;
             moveUpwards=moveLeft=moveDownwards=false;
             currentDirection="東";
             System.out.printf("朝向已更改為:%s%n",currentDirection);
         }
         
         break;
     case 5:  //向前移動
         if (moveRight)
             {
             currentDirection="東";
             if (penLocation)
                 for (int j=column;j<column+pace;j++)
                     positions[row][j]=1;
             column+=pace;
             System.out.printf("已向前移動%d步,當前位置:【%d,%d】,當前朝向:東%n",pace, row+1, column+1);
                          }
         else if(moveLeft)
        {currentDirection="西";;
             if (penLocation)
                 for (int j=column;j>column-pace;j--)
                     positions[row][j]=1;
             column-=pace;
             System.out.printf("已向前移動%d步,當前位置:[%d,%d],當前朝向:西%n",pace, row+1, column+1);
         }
         else if(moveDownwards)
         {currentDirection="南";;
             if (penLocation)
              for (int i=row;i<row+pace;i++)	//已重寫
                     positions[i][column]=1;
                 row+=pace;
                 System.out.printf("已向前移動%d步,當前位置:[%d,%d],當前朝向:南%n",pace, row+1, column+1);
                 }
         else if(moveUpwards)
        {currentDirection="北";;
             if (penLocation)
                 for (int i=row;i>row-pace;i--)
                     positions[i][column]=1;
                 row-=pace;
                 System.out.printf("已向前移動%d步,當前位置:[%d,%d],當前朝向:北%n",pace, row+1, column+1);
         }
         break;
     case 6://print turtle graphics,列印圖形
         for (int i=0;i<20;i++)
             {
             for (int j=0;j<20;j++)
             {
             if (positions[i][j]==0)
                 System.out.print("-");
             else
            	 System.out.print("@");
             }
             System.out.print("\n");
             }
         System.out.print("\n\n");
         break;
     case 7://clear turtle graphics,擦除當前圖形
         for (int i=0;i<20;i++)	//重置陣列
             for(int j=0;j<20;j++)
                 positions[i][j]=0;
         turtleBehaviour(6);  //繪製空白畫板
         row = column = 0; //重置畫筆位置為畫板左上角
         moveRight = true; //重置移動方向
         System.out.println("圖形已擦除。");
         break;
     case 9://terminate the program
    	 System.out.println("繪製完成!");
         break;
     
     }

        
     }

 }

 

彩蛋:

如果要輸出以下圖形,

 

對應的指令為:

指令 步長
5 3
3  
5 2
4  
2  
5 5
3  
5 1
3  
1  
5 1
2  
4  
5 1
3  
1  
5 1
4  
2  
5 1
3  
1  
5 1
4  
2  
5 1
3  
1  
5 1
4  
2  
5 1
3  
1  
5 1
4  
2  
5 1
3  
1  
5 1
4  
2  
5 1

可見,帶拐彎的圖形輸出指令比較冗長,比較耗時。 可見,這個海龜還有待進化!