33,010
社区成员
发帖
与我相关
我的任务
分享
#include "stdio.h"
#include <conio.h>
#include <malloc.h>
#include <string.h>
#define WINDOWS_MAX 3 /*柜台数*/
#define NeedServerTime 65535 /*需要服务时间*/
#define TRUE 1
#define FALSE 0
typedef enum CLIENT_TYPE
{
COMMON_CLIENT,
VIP_CLIENT
};
typedef struct _Customer_Type
{
unsigned short ID; /*从柜台那到的ID*/
unsigned long STimer_Need; /*该顾客需要服务的时间*/
unsigned long STimer_Count; /*柜台已经服务的时间*/
CLIENT_TYPE IsVIP; /*是否是VIP客户*/
struct _Customer_Type *next;
}Customer_Type;
typedef struct _Windows_Type
{
Customer_Type clientInfo; /*正在服务的客户信息*/
unsigned char IsIdlesse; /*柜台当前是否空闲*/
}Windows_Type;
unsigned short ClientCount=0; /*已经接待客户计数*/
unsigned short Queue_Count=0; /*排队客户计数*/
Customer_Type *head,*tail;
Windows_Type windows[WINDOWS_MAX];
void Init(void); /*初始化程序*/
int GetInput(void); /*检测是否有键盘输入,及取号客户类型*/
void GetID(CLIENT_TYPE); /*客户取号*/
void IsIdlesseWindow(void); /*是否有柜台空闲*/
void CallClient(int ); /*柜台叫号*/
void PrintStatus(void); /*打印当前窗口服务信息*/
/*检测是否有键盘输入,并范围操作类型*/
int GetInput()
{
if(kbhit()) /*是否有键盘输入*/
{
char input;
input=getch();
switch(input)
{
case 'E':case 'e': /*退出程序*/
return 1;
break;
case 'V':case 'v': /*VIP客户*/
GetID(VIP_CLIENT);
break;
default: /*普通客户*/
GetID(COMMON_CLIENT);
break;
}
}
return 0;
}
/*客户取号*/
void GetID(CLIENT_TYPE client_type)
{
Customer_Type *clt,*p;
clt=(Customer_Type *)malloc(sizeof(Customer_Type));
if(clt==NULL)
{
printf("malloc new client fail\n");
return;
}
ClientCount++; /*服务的客户计数*/
Queue_Count++;
/*本次客户信息初始化*/
clt->ID=ClientCount;
clt->STimer_Need=NeedServerTime;
clt->STimer_Count=0;
clt->IsVIP=client_type;
clt->next=NULL;
if(clt->IsVIP==COMMON_CLIENT) /*普通客户*/
{
if(head==NULL && tail==NULL) /*第一个排队的*/
{
head=tail=clt;
}
else /*排队的顾客*/
{
tail->next=clt;
tail=clt;
}
}
else /*VIP客户*/
{
if(head==NULL && tail==NULL) /*还没有人排队*/
{
head=tail=clt;
}
else
{
p=head;
while(p->next !=NULL) /*若前面没有VIP客户,该客户排第一个,否则排前面VIP客户后*/
{
if(p->IsVIP!= VIP_CLIENT)
break;
p=p->next ;
}
clt->next =p;
if(p==head)
head=clt;
if(p==tail)
tail=clt;
}
}
}
/*打印窗口服务信息*/
void PrintStatus(void)
{
char buff[300];
char *p;
p=buff;
sprintf(p,"Queue[%d] ",Queue_Count-1);
p+=strlen(p);
for(int i=0;i<WINDOWS_MAX;i++)
{
if(windows[i].IsIdlesse==TRUE)
{
sprintf(p,"WIN%1d-IDLESSE \t",i+1);
}
else
{
if(windows[i].clientInfo.IsVIP)
sprintf(p,"WIN%1d-Client[%04d][VIP] \t",i+1,windows[i].clientInfo.ID );
else
sprintf(p,"WIN%1d-Client[%04d] \t",i+1,windows[i].clientInfo.ID );
}
p+=strlen(p);
}
printf("%s\n",buff);
}
/*是否有柜台空闲*/
void IsIdlesseWindow(void)
{
for(int i=0;i<WINDOWS_MAX;i++)
{
if(windows[i].IsIdlesse==TRUE)
{
CallClient(i); /*叫下一个客户*/
}
else
{
windows[i].clientInfo.STimer_Count++;
if(windows[i].clientInfo.STimer_Count == windows[i].clientInfo.STimer_Need)/*该客户业务完成*/
{
windows[i].IsIdlesse=TRUE;
CallClient(i); /*叫下一个客户*/
}
}
}
}
/*叫下一个客户*/
void CallClient(int IdlesseWindow)
{
if(head==NULL && tail==NULL)/*没有客户在排队*/
return;
if(head==tail)/*最后一个在排队的客户*/
{
memcpy(&windows[IdlesseWindow].clientInfo.ID,head,sizeof(Customer_Type));
free(head);
head=tail=NULL;
windows[IdlesseWindow].IsIdlesse=FALSE;
PrintStatus(); /*打印窗口服务信息*/
printf("********************[No queue]*******************\n");
Queue_Count--;
return;
}
if(head!=tail)
{
Customer_Type *p;
p=head;
memcpy(&windows[IdlesseWindow].clientInfo.ID,head,sizeof(Customer_Type));
head=head->next ;
free(p);
windows[IdlesseWindow].IsIdlesse=FALSE;
PrintStatus(); /*打印窗口服务信息*/
Queue_Count--;
}
return;
}
/*初始化变量*/
void Init(void)
{
for(int i=0;i<WINDOWS_MAX;i++)
windows[i].IsIdlesse=TRUE;
head=tail=NULL;
}
int main(int argc, char* argv[])
{
Init(); /*初始化信息*/
while(1)
{
if(GetInput()) /*退出程序*/
break;
IsIdlesseWindow();
}
return 0;
}
Public Enum BANK_WINDOWS
UnServed '未被服务
WINDOW_1 '窗口1
WINDOW_2 '窗口2
WINDOW_3 '窗口3
End Enum
Public Enum CUSTOMER_CLASS
NORMAL_CUSTOMER
VIP_CUSTOMER
End Enum
Public Type Customer_Type
ID As Long '取的号
Service_Timer As Long '顾客需要服务的时间
Servied_Timer As Long '已经服务的时间
Window_ID As BANK_WINDOWS '所在窗口ID
Customer_Cls As CUSTOMER_CLASS '用户类型
End Type
Public Type Window_Type
Window_ID As Integer '窗口序号
Customer As Customer_Type '当前服务顾客
Is_Empty As Boolean '是否空闲
End Type
Const WINDOW_MAX = 3 '最大窗口数
Const SERVICE_TIME = 30 '每位顾客服务时间
Public Windows(1 To WINDOW_MAX) As Window_Type '窗口队列
Public Customer_Queue() As Customer_Type '顾客队列
Public Customer_Count As Long '接待客户计数
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long 'API判断数组为空
'******************************************************************************
'点击取号按钮取号
'取号
Public Function Entry_Queue(ByVal IsVip As Boolean)
Customer_Count = Customer_Count + 1
If SafeArrayGetDim(Customer_Queue) = 0 Then '第一个排队的顾客
ReDim Customer_Queue(0)
Customer_Queue(UBound(Customer_Queue)).ID = Customer_Count '该客户拿到的号码
If IsVip Then
Customer_Queue(UBound(Customer_Queue)).Customer_Cls = VIP_CUSTOMER 'VIP
Else
Customer_Queue(UBound(Customer_Queue)).Customer_Cls = NORMAL_CUSTOMER '非VIP
End If
Customer_Queue(UBound(Customer_Queue)).Service_Timer = SERVICE_TIME '顾客需要服务时间
Else '非第一个排队的顾客
ReDim Preserve Customer_Queue(UBound(Customer_Queue) + 1)
If IsVip Then 'VIP
Dim i
For i = 0 To UBound(Customer_Queue)
If Customer_Queue(i).Customer_Cls <> VIP_CUSTOMER Then
Dim j
For j = 0 To UBound(Customer_Queue) - i - 1
Customer_Queue(UBound(Customer_Queue) - j) = Customer_Queue(UBound(Customer_Queue) - j - 1)
Next j
Customer_Queue(i).ID = Customer_Count
Customer_Queue(i).Customer_Cls = VIP_CUSTOMER
Customer_Queue(i).Service_Timer = SERVICE_TIME
Exit For
End If
Next i
Else '非VIP
Customer_Queue(UBound(Customer_Queue)).ID = Customer_Count
Customer_Queue(UBound(Customer_Queue)).Customer_Cls = NORMAL_CUSTOMER
Customer_Queue(UBound(Customer_Queue)).Service_Timer = SERVICE_TIME
End If
End If
End Function
'********************************************************************************
'界面的显示部分
Private Function DisplayConent()
Dim i
For i = 1 To WINDOW_MAX
If Windows(i).Is_Empty = False Then
Dim idstr As String
idstr = Format(Windows(i).Customer.ID, "000000")
If Windows(i).Customer.Customer_Cls = VIP_CUSTOMER Then
idstr = idstr & " VIP"
End If
Form1.Label1(i - 1).Caption = "柜台" & i & " 客户:" & idstr & vbCrLf & Windows(i).Customer.Servied_Timer & "S"
Else
Form1.Label1(i - 1).Caption = "柜台" & i & "空闲"
End If
Next i
Form1.txt_Queue.Text = ""
If SafeArrayGetDim(Customer_Queue) = 0 Then Exit Function
For i = 0 To UBound(Customer_Queue)
Form1.txt_Queue.Text = Form1.txt_Queue.Text & Format(Customer_Queue(i).ID, "000000") & vbCrLf
Next i
End Function
'********************************************************************************
'叫号
Private Function CallCustomer(ByVal Empty_Window As Integer)
Dim i
If SafeArrayGetDim(Customer_Queue) = 0 Then Exit Function
Windows(Empty_Window).Is_Empty = False
Windows(Empty_Window).Customer = Customer_Queue(0)
If UBound(Customer_Queue) = 0 Then
Erase Customer_Queue
Exit Function
End If
For i = 0 To UBound(Customer_Queue) - 1
Customer_Queue(i) = Customer_Queue(i + 1)
Next i
ReDim Preserve Customer_Queue(UBound(Customer_Queue) - 1)
End Function
'********************************************************************************
'定时器处理,每隔一秒判断一次
Public Function Second_Handle()
Dim i
For i = 1 To WINDOW_MAX
If Windows(i).Is_Empty = True Then '柜台空闲,叫下一个顾客
Call CallCustomer(i)
Else
Windows(i).Customer.Servied_Timer = Windows(i).Customer.Servied_Timer + 1
If Windows(i).Customer.Servied_Timer = Windows(i).Customer.Service_Timer Then '顾客业务办理完
Windows(i).Is_Empty = True
End If
End If
Next i
Call DisplayConent '显示界面信息
End Function
'*********************************************************************************
'初试化部分
Private Function init()
Dim i
For i = 1 To WINDOW_MAX
Windows(i).Is_Empty = True
Next
CustomerCount = 0
End Function
'*********************************************************************************
'主程序
Sub Main()
Call init
Form1.Show
Form1.Timer1.Enabled = True
End Sub