1. 程式人生 > >Go語言(Golang)約瑟夫遊戲(Joseph)

Go語言(Golang)約瑟夫遊戲(Joseph)

package main

import (
	"fmt"
)

//假設是一群小孩在玩這個遊戲
//建立一個小孩的結構體
type BoyNode struct {
	No int //給每個小孩一個唯一的身份編號
	next *BoyNode //指向下一個小孩
}

//假設有number個小孩在玩遊戲
func AddBoyNode(number int)  *BoyNode {
	head := &BoyNode {} //先建立一個頭節點
	temp := &BoyNode {} //建立一個輔助節點
	for i := 1; i<= number; i++ {
		boy := &BoyNode {
			No : i,
		}
		if i == 1 {
			head = boy
			temp = boy
			temp.next = head
		} else {
			temp.next = boy
			temp.next.next = head
		}
		temp = temp.next
	}
	return head
}

//開始遊戲
func Play(head *BoyNode, a, b int) *BoyNode {
	temp := head   //輔助節點指向頭節點head
	helper := head	//輔助節點指向連結串列最後的節點
	//判斷如果沒有小孩無法遊戲
	if temp.next == nil {
		fmt.Println("沒有小孩,無法進行遊戲!")
		return head
	}
	//小孩只剩一個的時候退出遊戲
	if temp.next == head {
		fmt.Println("只有一個小孩了,遊戲結束!最後一個小孩為:")
		return head
	}
	//將helper指向最後一個小孩
	for {
		if helper.next == head {
			break
		}
		helper = helper.next
	}
	//迴圈找到從第a個小孩開始遊戲
	for {
		if temp.No == a {
			break
		}
		temp = temp.next
		helper = helper.next
	}
	//數到b時出列的小孩
	for i := 1; i < b; i++ {
		temp = temp.next
		helper = helper.next
	}
	//如果該小孩是第一個小孩,則將頭節點指向下一個小孩
	if temp == head {
		head = head.next
	}
	helper.next = temp.next

	fmt.Println()
	fmt.Printf("小男孩:%d出列!",temp.No)
	fmt.Println()
	ListBoyNode(head)
	//下一次遊戲從第a個小孩開始
	a = temp.next.No
	return Play(head,a,b)
}

//輸出顯示連結串列
func ListBoyNode(head *BoyNode) {
	temp := head
	for {
		fmt.Printf("小男孩:%d ==>",temp.No)
		temp = temp.next
		if temp == head {
			break
		}
	}
}


func main() {
	fmt.Println("請輸入有多少個小孩玩遊戲:")
	var number int
	fmt.Scan(&number)
	head := AddBoyNode(number)
	ListBoyNode(head)
	fmt.Println("請輸入從第幾個小孩開始遊戲:")
	var a int 
	fmt.Scan(&a)
	fmt.Println("請輸入數幾的小男孩出列:")
	var b int 
	fmt.Scan(&b)
	head = Play(head,a,b)
	ListBoyNode(head)
}