Example #1
0
func main() {
	// Print a nice separator at the end of execution so that 'make fancyrun' looks good
	defer fmt.Println("-------------------")

	// Initialize globals
	processing = false
	complete = make(chan bool)

	// Begin listening on the port passed on the command line
	listener := easynet.HostWithAddress(os.Args[1])
	defer listener.Close()

	// Set up a TCP connection to the master
	connectionToMaster := easynet.Accept(listener)
	defer connectionToMaster.Close()

	// Read configuration from the connection to master
	config = new(ttypes.CoordConfig)
	easynet.ReceiveJson(connectionToMaster, config)

	respondingToRequestsFor = 0
	infoQueue = make([][]ttypes.BotInfo, 1, config.NumTurns)

	// Confirm configuration
	connectionToMaster.Write([]uint8("connected"))

	// Set up bots and connect to adjacent coordinators
	setupAll(listener)
	// Remember to terminate all child processes upon termination of this process
	defer killChildren()

	// Close all connections when program terminates
	for _, conn := range adjsServe {
		defer conn.Close()
	}

	// Confirm setup
	connectionToMaster.Write([]uint8("setup complete"))

	fmt.Printf("%d sees data at start as: \n%v\n    grid: %v\n", config.Identifier, botInfosForNeighbor(0), config.Terrain)

	// Transition to both listening states
	go listenForMaster(connectionToMaster)
	go listenForPeer()

	// Wait for those loops to exit
	<-complete
	<-complete

	fmt.Printf("%d sees data at end as: \n%v\n    grid: %v\n", config.Identifier, botInfosForNeighbor(0), config.Terrain)

	// Confirm termination
	finalTally := new(ttypes.Finish)
	for _, s := range botStates {
		if !s.Dead() {
			finalTally.NumBots += 1
		}
	}
	easynet.SendJson(connectionToMaster, finalTally)
}
Example #2
0
func getAgentInfoFromNeighbors() []ttypes.BotInfo {
	otherInfos := make([]ttypes.BotInfo, len(botStates), len(botStates)*len(adjsServe))

	//Copy all infos from botStates into otherInfos
	for k, s := range botStates {
		otherInfos[k] = s.Info
	}

	//Get updates from neighbors
	for j, conn := range adjsRequest {
		fmt.Printf("%d turn %d, request neighbor %d\n", config.Identifier, respondingToRequestsFor, j)
		r := new(Request)
		r.Identifier = config.Identifier
		r.Turn = respondingToRequestsFor
		r.Command = "GetNodes"

		easynet.SendJson(conn, r)

		info := new(RespondNodeInfo)
		easynet.ReceiveJson(conn, info)

		otherInfos = append(otherInfos, info.BotData...)
	}
	return otherInfos
}
Example #3
0
func broadcastComplete() {
	note := new(Request)
	note.Identifier = config.Identifier
	note.Turn = respondingToRequestsFor
	note.Command = "Complete"

	for i, conn := range adjsRequest {
		fmt.Printf("%d broadcasting complete to %d\n", config.Identifier, i)
		easynet.SendJson(conn, note)
	}
}
Example #4
0
func handleRequest(data []uint8) {
	if processing == false {
		// The game's afoot!
		processing = true
		go processNodes()
	}
	r := new(Request)
	err := json.Unmarshal(data, r)
	easynet.DieIfError(err, "JSON error")
	switch {
	case r.Command == "GetNodes":
		fmt.Printf("%d handle GetNodes from %d\n", config.Identifier, r.Identifier)
		for respondingToRequestsFor < r.Turn {
			fmt.Printf("%d not ready for GetNodes\n", config.Identifier)
			time.Sleep(1000000)
		}

		fmt.Printf("%d ready for GetNodes\n", config.Identifier)
		info := new(RespondNodeInfo)
		info.Identifier = config.Identifier
		info.Turn = respondingToRequestsFor
		if lastInfoListCopied == 0 {
			info.BotData = botInfosForNeighbor(r.Identifier)
		} else {
			info.BotData = infoQueue[lastInfoListCopied][0:len(botStates)]
		}
		easynet.SendJson(adjsServe[r.Identifier], info)
		fmt.Printf("%d sent GetNodes response to %d\n", config.Identifier, r.Identifier)
		fmt.Printf("    and it was %v\n", info)

		neighborsLeftUntilUnlock -= 1
		if neighborsLeftUntilUnlock <= 0 {
			fmt.Printf("served all requests for %d\n", lastInfoListCopied)
			lastInfoListCopied += 1
			neighborsLeftUntilUnlock = len(adjsServe)
		}
	case r.Command == "Complete":
		completionsRemaining -= 1
		if completionsRemaining == 0 {
			fmt.Println("All neighbors complete, signaling TCOMPLETE2")
			complete <- true
		}
	}
}
Example #5
0
func killChild(s *BotState) {
	req := new(ttypes.BotMoveRequest)
	req.Kill = true
	easynet.SendJson(s.Conn, req)
}