跳轉到內容

從 Zip/陣列學習 Gambas 程式設計

來自華夏公益教科書

陣列、列表、排序和洗牌

[編輯 | 編輯原始碼]

有時您需要的不只是像速度、距離、時間這樣有單獨名稱的獨立記憶體,而是一個記憶體列表,一個變數集合,可以進行編號。所以你可能有 Speed[0],Speed[1],Speed[2] 等等,它們都儲存不同的速度,或者一個有像 Time[0],Time[1],Time[2] 等等名稱的幾個時間的列表。這被稱為陣列。

陣列中的元素(專案)從零開始編號,使用方括號。老師可能有一個學生名字的陣列,Student[0],Student[1] … Student[Student.Max]。陣列有一個計數(例如 Student.Count)和一個最大值 (Student.Max)。不要超過 Max,否則你會越界。這肯定意味著放學後留堂。

您可以擁有幾乎任何型別的陣列。但是,當您需要它們時,您需要使用 NEW 運算子來建立它們。

一個字串陣列

Dim Names As New String[]
Names = ["John", "Mary", "Lucy", "Owen", "Peter", "Clare", "Thomas"]

一個整數陣列,使用陣列的 Add 方法

Dim Numbers As New Integer[]
'put the numbers 8 to 28 into an array; Numbers[0] is 8; Numbers[20] is 28
For i as integer = 8 to 28 
   Numbers.add(i)
Next

陣列有 SortShuffle 方法。您可以編寫這些方法中的任何一個。gb.descent 及其配對項是 gb 元件中的常量。

Names.sort
Numbers.sort

Names.sort(gb.descent)
Numbers.sort(gb.descent)

Names.shuffle
Numbers.shuffle

要檢視您的陣列,在您的表單上放置一個列表框,然後將您的陣列放入其列表中。右側的陣列將進入左側列表框的列表中。程式碼看起來像這樣。更詳細的說明如下。

Listbox1.List = Names
Listbox1.List = Numbers

Gambas form with listbox and two buttons Shuffle and Sort, running


按鈕分別稱為 bShufflebSort

Public s As New String[]

Public Sub Form_Open()
  s = ["Apple", "Banana", "Carrot", "Dragonfruit", "Elderberry", "Fig", "Grape", "Honeydew", "Imbe", "Jackfruit", "Kiwi", "Lime"]
  ListBox1.List = s
End

Public Sub bSort_Click()
  s = ListBox1.List 'copy the list into array s[]
  ListBox1.List = s.Sort() 'put the sorted s[] into the listbox's list
End

Public Sub bShuffle_Click()
  s = ListBox1.List 'copy the list into array s[]
  s.Shuffle 'shuffle the array s[]
  ListBox1.List = s 'put s into the listbox's list
End

請注意,即使 ListBox1 的 List 屬性像陣列一樣工作,您也不能說 ListBox1.List.Shuffle。是的,它是一個數組。不,它沒有 Shuffle 方法。

與排序按鈕相比,洗牌按鈕的 Click 處理程式中多了一行。s.Sort() 是一個事物,一個函式s.Shuffle 是一個方法。它不是一個事物,而是一個過程,一個過程。它是一個當完成時不返回任何值的子程式。你不能把它放到任何東西中。如果您嘗試 ListBox1.List = s.shuffle(),您將收到錯誤訊息。Gambas 幫助顯示了它們的不同之處

Sort function defined in Gambas Help


Shuffle method defined in Gambas Help


按字母順序排序和按數字排序

[編輯 | 編輯原始碼]

帶數字的列表框需要按數字排序。按字母順序對 1 到 12 的數字進行排序將得到 1、10、11、12、2、3、4、5、6、7、8、9,因為按字母順序“10”在“2”之前。將列表複製到一個整數陣列中並對其進行排序

Public Sub bSort_Click()
  Dim x As New Integer[]
  x = ListBox1.List
  x.Sort
  ListBox1.List = x
End

您可以看到它在實際中的執行效果


Form to show alphabetic and numeric sorting Program running to demonstrate alphabetic and numeric shuffling

Public z As New Integer[]
Public s As New String[]

Public Sub Form_Open()
  For i As Integer = 1 To 12
    z.Add(i)
  Next
  z.Shuffle
  ListBox1.List = z
End

Public Sub Button1_Click()
  s = ListBox1.List
  ListBox1.List = s.Sort()
End

Public Sub Button2_Click()
  z = ListBox1.List
  ListBox1.List = z.Sort()
End

字串可以被視為字元陣列。因此,如果 Nm = "Gerard" 那麼 Nm[0]GNm[1]eNm[2]r 等等。

但是,您不能更改像 Nm[2]="x" 這樣的字母來使 Gerard 變成 Gexard。您可以 獲取 字母,但您不能 放入 任何東西。您必須使用字串具有的某些精彩函式。您可以使用這些函式中的任何一個來處理字串。您可以使用這些函式中的任何一個

Nm = Left(Nm,1) & “x” & Mid(Nm,3)

Nm = Left(Nm,1) & “x” & Right(Nm,4)

Nm = Replace(Nm, “e”, “x”)

Form with three buttons to demonstrate string functions Three buttons to demonstrate string functions, running

Public FirstName As String = "Gerard"

Public Sub b1_Click()
  Label1.Text = Left(FirstName, 1) & "x" & Mid(FirstName, 3)
End

Public Sub b2_Click()
  Label1.Text = Left(FirstName, 1) & "y" & Right(FirstName, 4)
End

Public Sub b3_Click()
  Label1.Text = Replace(FirstName, "e", "z")
End

陣列的陣列

[編輯 | 編輯原始碼]

您可以擁有一個列表排列的記憶體。它們將具有相同的名稱,但將像 X[0]X[1]X[2] 等等一樣編號

Numbering the elements of a 1-dimensional array

您可以將記憶體排列在一個網格(正方形或矩形)中,並透過行和列來引用它們。這也是 GridView 或 TableView 中單元格的編號方式

Numbering of elements in a 2-dimensional array

您可以將它們排列在一個立方體或稜柱體中,這樣就會有類似於矩形的層。方括號中的第三個數字表示哪一層。[行,列,層]

You can have them arranged in a cube or prism, so that there are like layers of rectangles. The third number in brackets tells which layer. [Row, Column, Layer]

您也可以擁有它們的陣列,但即使您可以擁有多維陣列,最常使用的是簡單的列表陣列。

平方表、平方根和計算

[編輯 | 編輯原始碼]

Gambas form with gridview and two buttons Table of Doubles, Squares and Square Roots

該程式用 1 到 10 的數字的計算填充網格。它還展示瞭如何調整 GridView 的屬性——它的列、行和單元格。

Public Sub Form_Open()
  Me.Show
  With gv1
    .Header = GridView.Horizontal
    .Columns.Count = 4
    .Columns[0].Width = 50
    .Columns[1].Width = 60
    .Columns[2].Width = 60
    .Columns[3].Width = 50
    .Columns[0].Text = ("Number")
    .Columns[1].Text = ("Square")
    .Columns[2].Text = ("Root")
    .Columns[3].Text = ("*3+5")
    For i As Integer = 0 To 3
      .Columns[i].Alignment = Align.Right
    Next
    .Padding = 5
  End With
End

Public Sub b1_Click()
  gv1.Rows.Count = 10
End

Public Sub bQuit_Click()
  Quit
End

Public Sub gv1_Data(Row As Integer, Column As Integer)

  Dim x As Integer = Row + 1
  Select Case Column
    Case 0
      gv1.Data.Text = x
    Case 1
      gv1.Data.Text = x ^ 2
    Case 2
      gv1.Data.Text = Format(Sqr(x), "##.000")
    Case 3
      gv1.Data.Text = x * 3 + 5
  End Select
  If Row Mod 2 = 0 Then gv1.Data.Background = &HBFFFBF

End

需要注意的是 With … End With 行,在表單開啟時設定 GridView,以及 _Data() 事件來填充每個單元格。gv1.Rows.Count = 10 足以觸發這十行的每個單元格的 Data() 事件。

當單元格需要繪製時,_Data() 事件就會發生。可以在單擊 Fill 按鈕時完成單元格的填充,但這樣我們就必須使用巢狀的 For 語句來對行進行向下計數,對列進行橫向計數。Gambas 已經必須這樣做,因為它必須繪製每個單元格。_Data() 事件發生在每行的每個單元格,所以為什麼不把文字放到單元格中呢?

如果 Row Mod 2 = 0 Then gv1.Data.Background = &HBFFFBF 將單元格的背景設定為薄荷綠,如果行號在除以 2 時餘數為零。Mod 表示“除以……時的餘數”。例如 3 Mod 2 是 1,所以第 3 行的背景是白色。4 Mod 2 是 0,因為 4 除以 2 等於 2 餘 0,所以第 4 行的背景是綠色。

我們可以使用兩種顏色交替,粉紅色和綠色

gv1.Data.Background = If(Row Mod 2 = 0, &HBFFFBF, &HFFCFCF)

要對列進行著色,請在 tv1_Data() 事件中嘗試以下操作


Gridview with coloured columns in Gambas


gv1.Data.Background = Choose(Column + 1, &FFAAFF, &FFFFAA, &AAFFFF, &AAAAFF)

Format(Sqr(x), "##.000") 是一個有趣的表示式。Format 函式接受一個浮點數,例如 1.41421356237,並根據提供的模式對其進行格式化。"##.000" 表示 如果需要則使用兩位數字,一個點,以及使用零的三位小數。要格式化的數字是什麼?Sqr(x)。這是數字 x 的平方根。2 的平方根顯示為 1.414。

格式函式

[編輯 | 編輯原始碼]
+ 列印數字的符號。
- 僅當數字為負時才打印數字的符號。
# 僅在必要時列印一個數字。
0 始終列印一個數字,並在必要時用零填充。
. 列印小數點。
, 列印千位分隔符。
% 將數字乘以 100 並列印一個百分號。
E 介紹 Float 數的指數部分。指數的符號始終會被列印。

還有更多用於格式化日期和貨幣的符號。

“哞”遊戲

[編輯 | 編輯原始碼]
Mastermind board game
妙探遊戲

為了玩“哞”遊戲,也稱為“牛和奶牛”,一個人(電腦!)選擇一個神秘數字。它有 4 位數字,所有數字都不相同。維基百科說,“帶釘子的現代遊戲由以色列郵政局長和電信專家 Mordecai Meirowitz 於 1970 年發明。它類似於一個更早的用鉛筆和紙玩的遊戲,稱為牛和奶牛,這個遊戲可能可以追溯到一個世紀甚至更久以前。”“哞”由麻省理工學院的 J. M. Grochow 於 1970 年使用 PL/I 計算機語言編寫。

每次猜測後,電腦會告訴你猜中了多少個“牛”和多少個“母牛”。“牛”是指你在數字中猜到的數字,並且在神秘數字中的位置是正確的。“母牛”是指你在數字中猜到的數字,但位置不對。因此,你的目標是BBBB,所有四個數字都在正確的位置。CCCC意味著你猜到了正確的數字,但它們不在正確的位置。BBC意味著兩個數字的位置正確,另一個數字在數字中但位置錯誤,而另一個數字則不在數字中。有些人按照規則玩,如果你在十回合或更少的回合內猜到,你就贏了。牛的數字先列出,然後是母牛的數字。你不會被告知哪些數字是牛,哪些是母牛。

你需要兩個文字框、一個名為gvHistory的網格檢視,以及一個名為bNewGame的按鈕,其文字屬性為“新遊戲”。

Gambas form for the game of Moo Gambas program for the game of Moo, running Congratulations message after the game of Moo in Gambas

“新遊戲”按鈕最初是不可見的。

Public MyNumber As String
Public Count As Integer

Public Sub Form_Open()
  gvHistory.Columns.Count = 2
  ChooseNumber
End

Public Sub ChooseNumber()
  Dim Digits As New String[]
  Dim i, p1, p2 As Integer
  Dim d As String
  For i = 0 To 9
    Digits.Add(Str(i))
  Next
  Digits.Shuffle
  MyNumber = Digits[0] & Digits[1] & Digits[2] & Digits[3]
End

Public Sub EvaluateGuess()  
  Dim s As String
  Dim i, j As Integer
  Dim YourGuess As String = tbGuess.text
  Count += 1
  For i = 0 To 3 'look for bulls
    If YourGuess[i] = MyNumber[i] Then s &= "B"
  Next
  For i = 0 To 3 'look for cows
    For j = 0 To 3
      If i <> j And YourGuess[i] = MyNumber[j] Then s &= "C"
    Next
  Next
  tbReply.Text = s
  gvHistory.Rows.Count += 1
  gvHistory[gvHistory.Rows.max, 0].text = YourGuess
  gvHistory[gvHistory.Rows.max, 1].text = s
  If s = "BBBB" Then Congratulate
  tbGuess.SelectAll
End

Public Sub Congratulate()  
  Message("<b>Congratulations!</b><br><br>Got it in " & count)
  FMain.Background = Color.Yellow '&FFFF00
  bNewGame.Visible = True  
End

Public Sub bNewGame_Click()
  FMain.Background = Color.Default
  bNewGame.Visible = False
  gvHistory.Rows.Count = 0
  Count = 0
  ChooseNumber
  tbReply.text = ""
  tbGuess.text = ""
  tbGuess.SetFocus
End

Public Sub tbGuess_Change()
  If Len(tbGuess.text) = 4 Then EvaluateGuess
End

現在開始回顧

有兩個公共變數。MyNumber 是電腦的秘密數字。Count 統計了猜測次數。

Form_Open() 啟動時,將網格檢視設定為 2 列,並選擇秘密數字。

Public Sub ChooseNumber() 將數字 0 到 9 放入一個名為 Digits 的 10 個元素的陣列中,並將其隨機排序。秘密數字是前四個數字。它們將是隨機的,並且不會重複。

Public Sub EvaluateGuess() 當你評估一個猜測時,它會多出一個猜測,所以將 Count 加 1。尋找牛:你的猜測中的第一個字元是否與數字中的第一個字元相同?檢查第二個、第三個和第四個字元也是一樣。每次兩個字元匹配時,就將 what s 是的內容新增到其末尾,並在其末尾新增一個 B,使用 s &= "B"

在尋找母牛時,i 會遍歷 0、1、2、3,每次都遍歷你的數字。對於你的數字中的每一個數字,檢查秘密數字中的所有數字,看看是否有匹配的,但不要考慮位置數字相同的情況(比如秘密數字中的第三個數字和我的猜測中的第三個數字),因為這是牛,並且已經找到了。

S 是一個變數,它包含 BBBB 或 BBCC 或 B 或其他內容。

在歷史網格檢視中新增一行,並將猜測放在第一列,將其評估放在第二列。

Public Sub Congratulate() 顯示一條訊息,說“恭喜你!你在 8 次嘗試內猜對了”或其他內容。將窗體的顏色更改為黃色。使“新遊戲”按鈕可見。

Public Sub bNewGame_Click() 要開始新遊戲,請刪除黃色,隱藏“新遊戲”按鈕,從歷史網格檢視中刪除所有內容,將猜測次數重置為零,選擇另一個數字,清空兩個文字框,並將焦點設定為用於輸入猜測的文字框,這樣你就可以開始輸入了。

Public Sub tbGuess_Change() 當“猜測”文字框中的文字因為你輸入了另一個數字而發生變化時,檢查輸入的內容的長度,如果它是 4 個字元長,就評估猜測。

新增“我放棄”功能

[edit | edit source]

讓我們將其設定為輸入問號意味著“我放棄——告訴我答案”。我們需要一個新的事件,tbGuess_KeyPress()。只要輸入了問號,這個處理程式就會檢查靜態類 Key,看看是否輸入了“?”字元。如果是,就向我們顯示正確的答案,並開始新遊戲。

開始新遊戲正是我們在“新遊戲”按鈕的 _Click 處理程式中所做的。這段程式碼需要從 _Click 處理程式中移出來,放到它自己的子程式中。當按鈕被點選或使用者透過輸入“?”放棄時,我們可以呼叫這個 NewGame 子程式。以下是重新排列的程式碼和額外的程式碼

Public Sub bNewGame_Click()
  NewGame
End

Public Sub NewGame()

  FMain.Background = Color.Default
  bNewGame.Visible = False
  gvHistory.Rows.Count = 0
  Count = 0
  ChooseNumber
  tbReply.text = ""
  tbGuess.text = ""
  tbGuess.SetFocus

End

Public Sub tbGuess_KeyPress()

  If Key.Text = "?" Then
    Message("My number was " & MyNumber)
    NewGame
    Stop Event
  Endif

End

Stop Event 用於防止問號出現在 tbGuess 文字框中。這不是必須的。

重要的原則是(你可以記住它,或者把它當作金科玉律),如果你想在兩個或多個地方引用相同的程式碼行,請將它們放在自己的子程式中,並透過名稱呼叫它們

賦值運算子

[edit | edit source]
x = x+2 將 2 加到 x 的原來值上,然後將答案放回 x 中。
x += 2 同樣的事情:x 變成原來值 (=),加上 (+) 2。
x = x * 4 x 乘以 4,並將答案放回 x 中。
x *= 4 同樣的事情:x 變成原來值 (=),乘以 (*) 4。
s = s & "abc" s 變成原來值 (&),在末尾附加 “abc”。
s &= "abc" 同樣的事情:s 變成原來值 (=),在末尾附加 (&) “abc”。

還有數值運算子,包括 ^ 表示“乘方”。布林運算子是 AND、OR 和 NOT。還有其他運算子,但這些是最常用的和最實用的。

從 Zip 檔案中程式設計 Gambas
 ← ThreeThings 陣列 TextFiles → 
華夏公益教科書