<commit_before>package rtsengine

import (
	"fmt"
	"image"
	"io"
)

// HumanPlayer implements the IPlayer interface for a human player
type HumanPlayer struct {
	// Structures common to all players.
	BasePlayer

	// Live TCPWire to communicate with UI
	Wire *TCPWire
}

// NewHumanPlayer constructs a HumanPlayer
func NewHumanPlayer(description string, worldLocation image.Point, width int, height int, pool *Pool, pathing *AStarPathing, world *World) *HumanPlayer {
	player := HumanPlayer{}

	player.description = description
	player.GenerateView(worldLocation, width, height)
	player.ItemPool = pool
	player.Pathing = pathing
	player.OurWorld = world

	player.Map = make(map[IUnit]IUnit)

	// Add mechanics

	return &player
}

/////////////////////////////////////////////////////////////////////////
//                           IPlayer interface                         //
/////////////////////////////////////////////////////////////////////////
func (player *HumanPlayer) listen(wire *TCPWire) {
	player.Wire = wire
}

func (player *HumanPlayer) isHuman() bool {
	return true
}

func (player *HumanPlayer) isWireAlive() bool {
	// Best guess
	return player.Wire != nil
}

func (player *HumanPlayer) start() error {

	if !player.isWireAlive() {
		return fmt.Errorf("Failed: This player does not have an active wire connection.")
	}

	go player.listenForWireCommands()
	return nil
}

func (player *HumanPlayer) stop() {
	if player.isWireAlive() {
		// Will stop the listenForWireCommands coroutine
		err := player.Wire.Connection.Close()
		if err != nil {
			fmt.Println(err)
		}
		player.Wire = nil
	}
}

/////////////////////////////////////////////////////////////////////////
//                           IPlayer interface                         //
/////////////////////////////////////////////////////////////////////////

// listenForWireCommands will listend for commands from a human player
// and will perform the proper command responses.
func (player *HumanPlayer) listenForWireCommands() {
	var packet WirePacket
	for {

		// Blocking call
		if player.Wire.ReceiveCheckEOF(&packet) {
			fmt.Println("\n\nEOF was detected. Connection lost.")
			return // stops this coroutine
		}
		packet.Print()
		err := player.dispatch(&packet)
		if err != nil {
			// Stop the cooroutine
			return
		}

	} // for ever
}

func (player *HumanPlayer) dispatch(packet *WirePacket) error {
	switch packet.Command {
	case ScrollView:
		// TODO: Ensure the scroll is within the world.
		player.WorldOrigin.X += packet.CurrentX
		player.WorldOrigin.Y += packet.CurrentY
		player.refreshPlayerToUI(true)

	case MoveUnit:
		if player.In(&image.Point{packet.WorldX, packet.WorldY}) {
			packetArray := make([]WirePacket, 1)
			packetArray[0] = *packet

			if err := player.Wire.Send(packetArray); err == io.EOF {
				fmt.Println("\n\nEOF was detected. Connection lost.")
				return err<commit_msg>Clips the view scroll to the world grid.<commit_after>package rtsengine

import (
	"fmt"
	"image"
	"io"
)

// HumanPlayer implements the IPlayer interface for a human player
type HumanPlayer struct {
	// Structures common to all players.
	BasePlayer

	// Live TCPWire to communicate with UI
	Wire *TCPWire
}

// NewHumanPlayer constructs a HumanPlayer
func NewHumanPlayer(description string, worldLocation image.Point, width int, height int, pool *Pool, pathing *AStarPathing, world *World) *HumanPlayer {
	player := HumanPlayer{}

	player.description = description
	player.GenerateView(worldLocation, width, height)
	player.ItemPool = pool
	player.Pathing = pathing
	player.OurWorld = world

	player.Map = make(map[IUnit]IUnit)

	// Add mechanics

	return &player
}

/////////////////////////////////////////////////////////////////////////
//                           IPlayer interface                         //
/////////////////////////////////////////////////////////////////////////
func (player *HumanPlayer) listen(wire *TCPWire) {
	player.Wire = wire
}

func (player *HumanPlayer) isHuman() bool {
	return true
}

func (player *HumanPlayer) isWireAlive() bool {
	// Best guess
	return player.Wire != nil
}

func (player *HumanPlayer) start() error {

	if !player.isWireAlive() {
		return fmt.Errorf("Failed: This player does not have an active wire connection.")
	}

	go player.listenForWireCommands()
	return nil
}

func (player *HumanPlayer) stop() {
	if player.isWireAlive() {
		// Will stop the listenForWireCommands coroutine
		err := player.Wire.Connection.Close()
		if err != nil {
			fmt.Println(err)
		}
		player.Wire = nil
	}
}

/////////////////////////////////////////////////////////////////////////
//                           IPlayer interface                         //
/////////////////////////////////////////////////////////////////////////

// listenForWireCommands will listend for commands from a human player
// and will perform the proper command responses.
func (player *HumanPlayer) listenForWireCommands() {
	var packet WirePacket
	for {

		// Blocking call
		if player.Wire.ReceiveCheckEOF(&packet) {
			fmt.Println("\n\nEOF was detected. Connection lost.")
			return // stops this coroutine
		}
		packet.Print()
		err := player.dispatch(&packet)
		if err != nil {
			// Stop the cooroutine
			return
		}

	} // for ever
}

func (player *HumanPlayer) dispatch(packet *WirePacket) error {
	switch packet.Command {
	case ScrollView:
		// TODO: Ensure the scroll is within the world.
		X1 := player.WorldOrigin.X + packet.CurrentX
		Y1 := player.WorldOrigin.Y + packet.CurrentY
		point := image.Rect(X1, Y1, X1+player.Span.Dx(), Y1+player.Span.Dy())

		if point.In(player.OurWorld.Span) {
			player.WorldOrigin.X += packet.CurrentX
			player.WorldOrigin.Y += packet.CurrentY
			player.refreshPlayerToUI(true)
		}

	case MoveUnit:
		if player.In(&image.Point{packet.WorldX, packet.WorldY}) {
			packetArray := make([]WirePacket, 1)
			packetArray[0] = *packet

			if err := player.Wire.Send(packetArray); err == io.EOF {
				fmt.Println("\n\nEOF was detected. Connection lost.")
				return err
{'fraction_non_alphanumeric': 0.1947814525511052, 'fraction_numerical': 0.0016619577862722287, 'mean_word_length': 2.2096, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1436671', 'n_tokens_mistral': 1830, 'n_tokens_neox': 1662, 'n_words': 487}